diff --git a/doc/appdev-logging.rst b/doc/appdev-logging.rst
new file mode 100644
index 0000000..0be1d62
--- /dev/null
+++ b/doc/appdev-logging.rst
@@ -0,0 +1,218 @@
+.. appdev-logging
+
+.. _appdevlogging:
+
+Logging System
+==============
+
+The *x0-framework* provides a configurable logging mechanism through the ``sysLogger`` class.
+This logging system replaces direct ``console.debug()`` calls and allows fine-grained control
+over log output based on configurable debug levels.
+
+Overview
+--------
+
+The logging system is designed to:
+
+* Reduce performance impact of debug statements in production
+* Provide configurable log levels from the PostgreSQL backend
+* Support standard logging levels (ERROR, WARN, INFO, DEBUG)
+* Maintain backward compatibility with existing code
+
+Configuration
+-------------
+
+The logging level is configured in the PostgreSQL database via the ``debug_level`` configuration:
+
+.. code-block:: sql
+
+ INSERT INTO system.config (config_group, "value")
+ VALUES ('debug_level', '10');
+
+Log Levels
+----------
+
+The following log levels are available:
+
+=============== ======= =====================================================
+Level Name Value Description
+=============== ======= =====================================================
+LOG_LEVEL_NONE 0 No logging (production)
+LOG_LEVEL_ERROR 1 Only error messages
+LOG_LEVEL_WARN 5 Warnings and errors
+LOG_LEVEL_INFO 8 Informational messages, warnings, and errors
+LOG_LEVEL_DEBUG 10 All messages including debug output
+=============== ======= =====================================================
+
+Usage
+-----
+
+The logger is accessible globally through ``sysFactory.Logger`` after initialization.
+
+Basic Logging
+^^^^^^^^^^^^^
+
+.. code-block:: javascript
+
+ // Debug messages (level 10)
+ sysFactory.Logger.debug('Debug message:', objectData);
+
+ // Info messages (level 8)
+ sysFactory.Logger.info('User logged in:', userId);
+
+ // Warning messages (level 5)
+ sysFactory.Logger.warn('Deprecated function called:', functionName);
+
+ // Error messages (level 1)
+ sysFactory.Logger.error('Operation failed:', errorDetails);
+
+Custom Log Levels
+^^^^^^^^^^^^^^^^^
+
+You can also use custom log levels:
+
+.. code-block:: javascript
+
+ // Log with custom level (7)
+ sysFactory.Logger.log(7, 'Custom level message:', data);
+
+Getting/Setting Log Level
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: javascript
+
+ // Get current log level
+ var currentLevel = sysFactory.Logger.getLogLevel();
+
+ // Set log level programmatically (not recommended, use config instead)
+ sysFactory.Logger.setLogLevel(5); // Set to WARN level
+
+Examples
+--------
+
+Basic Usage
+^^^^^^^^^^^
+
+.. code-block:: javascript
+
+ function sysReactor() {
+ this.Events = new Array();
+ sysFactory.Logger.debug('Reactor initialized with events array');
+ }
+
+ sysReactor.prototype.registerEvent = function(Attributes, ProcessObject, Type) {
+ sysFactory.Logger.debug('registerEvent Attributes:%o ProcessObject:%o, Type:%s',
+ Attributes, ProcessObject, Type);
+ // ... rest of implementation
+ }
+
+Conditional Logging
+^^^^^^^^^^^^^^^^^^^
+
+.. code-block:: javascript
+
+ function processData(data) {
+ try {
+ // Process data
+ sysFactory.Logger.info('Data processed successfully');
+ } catch (err) {
+ sysFactory.Logger.error('Data processing failed:', err);
+ }
+ }
+
+Migration Guide
+---------------
+
+Existing ``console.debug()`` calls can be gradually migrated to use the logger:
+
+Before:
+
+.. code-block:: javascript
+
+ console.debug('TreeSimple JSONConfig:%o', Attributes);
+
+After:
+
+.. code-block:: javascript
+
+ sysFactory.Logger.debug('TreeSimple JSONConfig:%o', Attributes);
+
+Benefits
+--------
+
+Using the logger class provides several advantages:
+
+1. **Performance**: Logging can be completely disabled in production (level 0)
+2. **Flexibility**: Different log levels can be enabled without code changes
+3. **Consistency**: Standardized logging interface across the framework
+4. **Control**: Centralized configuration through the database
+
+Best Practices
+--------------
+
+1. Use appropriate log levels:
+
+ * ``debug()`` for detailed debugging information
+ * ``info()`` for general informational messages
+ * ``warn()`` for warning messages about potential issues
+ * ``error()`` for error conditions
+
+2. Include context in log messages:
+
+ .. code-block:: javascript
+
+ // Good - includes context
+ sysFactory.Logger.debug('User validation failed for ID:%s', userId);
+
+ // Poor - lacks context
+ sysFactory.Logger.debug('Validation failed');
+
+3. Use structured logging with objects:
+
+ .. code-block:: javascript
+
+ sysFactory.Logger.debug('Request data:', {
+ url: requestUrl,
+ method: requestMethod,
+ params: requestParams
+ });
+
+4. Avoid logging sensitive information:
+
+ .. code-block:: javascript
+
+ // Avoid logging passwords, tokens, or personal data
+ sysFactory.Logger.debug('User logged in', { userId: user.id }); // OK
+ // NOT: sysFactory.Logger.debug('Login', { password: user.password }); // NEVER!
+
+Technical Details
+-----------------
+
+Implementation
+^^^^^^^^^^^^^^
+
+The ``sysLogger`` class is implemented in ``/www/sysLogger.js`` and provides:
+
+* Constructor: ``sysLogger()``
+* Methods:
+
+ * ``setLogLevel(level)`` - Set the logging level
+ * ``getLogLevel()`` - Get the current logging level
+ * ``debug(...)`` - Log debug messages
+ * ``info(...)`` - Log info messages
+ * ``warn(...)`` - Log warning messages
+ * ``error(...)`` - Log error messages
+ * ``log(level, ...)`` - Log with custom level
+
+Initialization
+^^^^^^^^^^^^^^
+
+The logger is initialized in ``sysInitOnLoad.js`` during application startup:
+
+.. code-block:: javascript
+
+ sysFactory.Logger = new sysLogger();
+ sysFactory.Logger.setLogLevel(sysVarDebugLevel);
+
+The ``sysVarDebugLevel`` value is injected from the Python backend (``Index.py``)
+based on the PostgreSQL configuration.
diff --git a/doc/index.rst b/doc/index.rst
index 98897f8..be805be 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -15,6 +15,7 @@ x0 Framework Documentation
:caption: Application Development Guide
appdev-config
+ appdev-logging
appdev-global-css
appdev-grid-system
appdev-objects
diff --git a/python/Index.py b/python/Index.py
index 9930fbd..7b0546a 100755
--- a/python/Index.py
+++ b/python/Index.py
@@ -20,6 +20,7 @@
+
diff --git a/test/integration/test_logger.py b/test/integration/test_logger.py
new file mode 100644
index 0000000..c093733
--- /dev/null
+++ b/test/integration/test_logger.py
@@ -0,0 +1,187 @@
+import os
+import json
+import time
+import pytest
+import logging
+
+import globalconf
+
+from selenium import webdriver
+from selenium.webdriver.common.by import By
+from selenium.webdriver.common.keys import Keys
+from selenium.webdriver.support.ui import WebDriverWait
+from selenium.webdriver.support import expected_conditions as EC
+
+logging.basicConfig(level=logging.DEBUG)
+logger = logging.getLogger()
+
+wd_options = webdriver.ChromeOptions()
+wd_options.add_argument('ignore-certificate-errors')
+wd_options.add_argument('headless')
+
+
+@pytest.fixture(scope='module')
+def config():
+
+ try:
+ run_namespace = os.environ['RUN_NAMESPACE']
+ except Exception as e:
+ run_namespace = None
+
+ try:
+ run_kube_env = os.environ['KUBERNETES_SERVICE_HOST']
+ except Exception as e:
+ run_kube_env = None
+
+ try:
+ domain_suffix = '.' + run_namespace
+ except Exception as e:
+ domain_suffix = ''
+
+ if run_kube_env is not None:
+ domain_suffix += '.svc.cluster.local'
+
+ vhost_test_urls = globalconf.setup()
+
+ logger.info('test urls:{}'.format(vhost_test_urls))
+
+ selenium_server_url = 'http://selenium-server-0{}:4444'.format(domain_suffix)
+
+ logger.info('selenium server url:{}'.format(selenium_server_url))
+
+ config = {
+ 'vhost_test_urls': vhost_test_urls,
+ 'selenium_server_url': selenium_server_url,
+ 'timeout': 60
+ }
+
+ return config
+
+
+@pytest.fixture(scope='module')
+def driver(config):
+
+ selenium_server_url = config['selenium_server_url']
+
+ driver = webdriver.Remote(
+ command_executor=selenium_server_url,
+ options=wd_options
+ )
+
+ driver.implicitly_wait(config['timeout'])
+
+ yield driver
+
+ driver.quit()
+
+
+def test_logger_initialization(driver, config):
+ """Test that sysLogger is properly initialized"""
+
+ test_url = config['vhost_test_urls'][0]
+ logger.info('Test URL: {}'.format(test_url))
+
+ driver.get(test_url)
+
+ # Wait for page to load
+ time.sleep(3)
+
+ # Check that sysFactory exists
+ result = driver.execute_script("return typeof sysFactory !== 'undefined';")
+ assert result == True, "sysFactory should be defined"
+
+ # Check that Logger exists on sysFactory
+ result = driver.execute_script("return typeof sysFactory.Logger !== 'undefined';")
+ assert result == True, "sysFactory.Logger should be defined"
+
+ # Check that Logger is an instance of sysLogger
+ result = driver.execute_script("return sysFactory.Logger instanceof sysLogger;")
+ assert result == True, "sysFactory.Logger should be an instance of sysLogger"
+
+ logger.info('Logger initialization test passed')
+
+
+def test_logger_methods_exist(driver, config):
+ """Test that all logger methods exist"""
+
+ test_url = config['vhost_test_urls'][0]
+ driver.get(test_url)
+ time.sleep(3)
+
+ # Check for debug method
+ result = driver.execute_script("return typeof sysFactory.Logger.debug === 'function';")
+ assert result == True, "Logger should have debug method"
+
+ # Check for info method
+ result = driver.execute_script("return typeof sysFactory.Logger.info === 'function';")
+ assert result == True, "Logger should have info method"
+
+ # Check for warn method
+ result = driver.execute_script("return typeof sysFactory.Logger.warn === 'function';")
+ assert result == True, "Logger should have warn method"
+
+ # Check for error method
+ result = driver.execute_script("return typeof sysFactory.Logger.error === 'function';")
+ assert result == True, "Logger should have error method"
+
+ # Check for log method
+ result = driver.execute_script("return typeof sysFactory.Logger.log === 'function';")
+ assert result == True, "Logger should have log method"
+
+ # Check for setLogLevel method
+ result = driver.execute_script("return typeof sysFactory.Logger.setLogLevel === 'function';")
+ assert result == True, "Logger should have setLogLevel method"
+
+ # Check for getLogLevel method
+ result = driver.execute_script("return typeof sysFactory.Logger.getLogLevel === 'function';")
+ assert result == True, "Logger should have getLogLevel method"
+
+ logger.info('Logger methods test passed')
+
+
+def test_logger_level_configuration(driver, config):
+ """Test that logger respects debug level from configuration"""
+
+ test_url = config['vhost_test_urls'][0]
+ driver.get(test_url)
+ time.sleep(3)
+
+ # Get the configured log level
+ result = driver.execute_script("return sysFactory.Logger.getLogLevel();")
+ logger.info('Current log level: {}'.format(result))
+
+ # The default configuration should be 10 (DEBUG)
+ assert result >= 0, "Log level should be >= 0"
+
+ # Test that we can change the log level
+ driver.execute_script("sysFactory.Logger.setLogLevel(5);")
+ result = driver.execute_script("return sysFactory.Logger.getLogLevel();")
+ assert result == 5, "Log level should be 5 after setting"
+
+ logger.info('Logger level configuration test passed')
+
+
+def test_logger_constants(driver, config):
+ """Test that logger constants are defined"""
+
+ test_url = config['vhost_test_urls'][0]
+ driver.get(test_url)
+ time.sleep(3)
+
+ # Check log level constants
+ result = driver.execute_script("return sysLogger.LOG_LEVEL_NONE;")
+ assert result == 0, "LOG_LEVEL_NONE should be 0"
+
+ result = driver.execute_script("return sysLogger.LOG_LEVEL_ERROR;")
+ assert result == 1, "LOG_LEVEL_ERROR should be 1"
+
+ result = driver.execute_script("return sysLogger.LOG_LEVEL_WARN;")
+ assert result == 5, "LOG_LEVEL_WARN should be 5"
+
+ result = driver.execute_script("return sysLogger.LOG_LEVEL_INFO;")
+ assert result == 8, "LOG_LEVEL_INFO should be 8"
+
+ result = driver.execute_script("return sysLogger.LOG_LEVEL_DEBUG;")
+ assert result == 10, "LOG_LEVEL_DEBUG should be 10"
+
+ logger.info('Logger constants test passed')
diff --git a/www/sysInitOnLoad.js b/www/sysInitOnLoad.js
index fd109ae..e1d7a39 100644
--- a/www/sysInitOnLoad.js
+++ b/www/sysInitOnLoad.js
@@ -137,6 +137,14 @@ function InitOk(XHR) {
sysFactory.ParentWindowURL = sysVarParentWindowURL;
+ //----------------------------------------------------------------------------
+ //- Initialize Logger
+ //----------------------------------------------------------------------------
+
+ sysFactory.Logger = new sysLogger();
+ sysFactory.Logger.setLogLevel(sysVarDebugLevel);
+
+
//----------------------------------------------------------------------------
//- Style Defaults
//----------------------------------------------------------------------------
diff --git a/www/sysLogger.README.md b/www/sysLogger.README.md
new file mode 100644
index 0000000..d4a15fd
--- /dev/null
+++ b/www/sysLogger.README.md
@@ -0,0 +1,126 @@
+# sysLogger - Configurable Logging for x0 Framework
+
+## Overview
+
+The `sysLogger` class provides a configurable logging mechanism for the x0 JavaScript framework. It replaces direct `console.debug()` calls and allows fine-grained control over log output based on configurable debug levels.
+
+## Quick Start
+
+The logger is available globally after initialization:
+
+```javascript
+// Basic usage
+sysFactory.Logger.debug('Debug message');
+sysFactory.Logger.info('Info message');
+sysFactory.Logger.warn('Warning message');
+sysFactory.Logger.error('Error message');
+
+// With formatting
+sysFactory.Logger.debug('User data: %o', userData);
+sysFactory.Logger.info('Processing item %d of %d', current, total);
+```
+
+## Configuration
+
+The logging level is configured in the PostgreSQL database:
+
+```sql
+-- Default configuration
+INSERT INTO system.config (config_group, "value")
+VALUES ('debug_level', '10');
+```
+
+## Log Levels
+
+| Level | Name | Value | Description |
+|-------|------|-------|-------------|
+| NONE | `LOG_LEVEL_NONE` | 0 | No logging (production) |
+| ERROR | `LOG_LEVEL_ERROR` | 1 | Only error messages |
+| WARN | `LOG_LEVEL_WARN` | 5 | Warnings and errors |
+| INFO | `LOG_LEVEL_INFO` | 8 | Info, warnings, and errors |
+| DEBUG | `LOG_LEVEL_DEBUG` | 10 | All messages (development) |
+
+## Migration from console.debug()
+
+Replace existing console calls:
+
+```javascript
+// Before
+console.debug('TreeSimple JSONConfig:%o', Attributes);
+
+// After
+sysFactory.Logger.debug('TreeSimple JSONConfig:%o', Attributes);
+```
+
+## Benefits
+
+1. **Performance**: Logging can be completely disabled in production (level 0)
+2. **Flexibility**: Different log levels without code changes
+3. **Consistency**: Standardized logging interface
+4. **Control**: Centralized configuration through database
+
+## Documentation
+
+For complete documentation, see `/doc/appdev-logging.rst`
+
+## Testing
+
+Run the integration tests:
+
+```bash
+pytest test/integration/test_logger.py
+```
+
+## Examples
+
+### Basic Logging
+
+```javascript
+function processData(data) {
+ sysFactory.Logger.debug('Processing data:', data);
+
+ try {
+ // Process data
+ sysFactory.Logger.info('Data processed successfully');
+ } catch (err) {
+ sysFactory.Logger.error('Data processing failed:', err);
+ }
+}
+```
+
+### Conditional Logging with Objects
+
+```javascript
+sysReactor.prototype.registerEvent = function(Attributes, ProcessObject, Type) {
+ sysFactory.Logger.debug('registerEvent - Attributes:%o ProcessObject:%o Type:%s',
+ Attributes, ProcessObject, Type);
+ // ... implementation
+}
+```
+
+### Custom Log Levels
+
+```javascript
+// Log only if level >= 7
+sysFactory.Logger.log(7, 'Custom level message', data);
+```
+
+## API Reference
+
+### Methods
+
+- `debug(...)` - Log debug messages (level 10)
+- `info(...)` - Log info messages (level 8)
+- `warn(...)` - Log warning messages (level 5)
+- `error(...)` - Log error messages (level 1)
+- `log(level, ...)` - Log with custom level
+- `setLogLevel(level)` - Set the logging level
+- `getLogLevel()` - Get the current logging level
+
+### Constants
+
+- `sysLogger.LOG_LEVEL_NONE` = 0
+- `sysLogger.LOG_LEVEL_ERROR` = 1
+- `sysLogger.LOG_LEVEL_WARN` = 5
+- `sysLogger.LOG_LEVEL_INFO` = 8
+- `sysLogger.LOG_LEVEL_DEBUG` = 10
diff --git a/www/sysLogger.js b/www/sysLogger.js
new file mode 100644
index 0000000..ee4d595
--- /dev/null
+++ b/www/sysLogger.js
@@ -0,0 +1,114 @@
+//-------1---------2---------3---------4---------5---------6---------7--------//
+//- Copyright WEB/codeX, clickIT 2011 - 2025 -//
+//-------1---------2---------3---------4---------5---------6---------7--------//
+//- -//
+//-------1---------2---------3---------4---------5---------6---------7--------//
+//- SYSTEM "Logger" -//
+//-------1---------2---------3---------4---------5---------6---------7--------//
+//- Configurable logging mechanism with debug level support -//
+//- -//
+//- -//
+//-------1---------2---------3---------4---------5---------6---------7--------//
+
+
+//------------------------------------------------------------------------------
+//- CONSTRUCTOR "sysLogger"
+//------------------------------------------------------------------------------
+
+function sysLogger() {
+ this.logLevel = 0; // Default: no logging
+ this.enabled = false;
+}
+
+
+//------------------------------------------------------------------------------
+//- Log Level Constants
+//------------------------------------------------------------------------------
+
+sysLogger.LOG_LEVEL_NONE = 0;
+sysLogger.LOG_LEVEL_ERROR = 1;
+sysLogger.LOG_LEVEL_WARN = 5;
+sysLogger.LOG_LEVEL_INFO = 8;
+sysLogger.LOG_LEVEL_DEBUG = 10;
+
+
+//------------------------------------------------------------------------------
+//- METHOD "setLogLevel"
+//- Sets the current logging level
+//------------------------------------------------------------------------------
+
+sysLogger.prototype.setLogLevel = function(level) {
+ this.logLevel = parseInt(level) || 0;
+ this.enabled = this.logLevel > 0;
+}
+
+
+//------------------------------------------------------------------------------
+//- METHOD "getLogLevel"
+//- Gets the current logging level
+//------------------------------------------------------------------------------
+
+sysLogger.prototype.getLogLevel = function() {
+ return this.logLevel;
+}
+
+
+//------------------------------------------------------------------------------
+//- METHOD "debug"
+//- Logs debug messages (level 10)
+//------------------------------------------------------------------------------
+
+sysLogger.prototype.debug = function() {
+ if (this.enabled && this.logLevel >= sysLogger.LOG_LEVEL_DEBUG) {
+ console.debug.apply(console, arguments);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//- METHOD "info"
+//- Logs info messages (level 8)
+//------------------------------------------------------------------------------
+
+sysLogger.prototype.info = function() {
+ if (this.enabled && this.logLevel >= sysLogger.LOG_LEVEL_INFO) {
+ console.info.apply(console, arguments);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//- METHOD "warn"
+//- Logs warning messages (level 5)
+//------------------------------------------------------------------------------
+
+sysLogger.prototype.warn = function() {
+ if (this.enabled && this.logLevel >= sysLogger.LOG_LEVEL_WARN) {
+ console.warn.apply(console, arguments);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//- METHOD "error"
+//- Logs error messages (level 1)
+//------------------------------------------------------------------------------
+
+sysLogger.prototype.error = function() {
+ if (this.enabled && this.logLevel >= sysLogger.LOG_LEVEL_ERROR) {
+ console.error.apply(console, arguments);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//- METHOD "log"
+//- Generic log method with custom level
+//------------------------------------------------------------------------------
+
+sysLogger.prototype.log = function(level) {
+ if (this.enabled && this.logLevel >= level) {
+ var args = Array.prototype.slice.call(arguments, 1);
+ console.log.apply(console, args);
+ }
+}