name: "Lucee Monitors" technology: "Lucee Extension Framework" since: "5.3" prerequisite: config_requirement: property: "monitoring.enabled" value: true location: ".CFConfig.json" default: false configuration: cfconfig_json: location: ".CFConfig.json" property: "monitoring.monitor" format: "Array of objects" schema: name: type: "string" required: true description: "Unique monitor identifier" type: type: "string" required: true values: ["action", "request", "interval"] class: type: "string" required: true description: "Full Java class name" bundleName: type: "string" required: false description: "OSGi bundle symbolic name" bundleVersion: type: "string" required: false description: "OSGi bundle version" log: type: "boolean" required: false default: true description: "Enable monitor logging" async: type: "boolean" required: false default: false description: "Asynchronous execution (request monitors only)" extension_manifest: location: "META-INF/MANIFEST.MF" property: "monitor" format: "JSON array string" schema: name: type: "string" required: true type: type: "string" required: true values: ["action", "request", "interval"] class: type: "string" required: true bundleName: type: "string" required: true description: "Required in manifest format" bundleVersion: type: "string" required: true description: "Required in manifest format" monitor_types: action: interface: "lucee.runtime.monitor.ActionMonitor" base_interface: "lucee.runtime.monitor.Monitor" trigger: "Synchronous during specific operations" thread_context: "Operation execution thread" operations: query: call: "((ConfigWebPro)pageContext.getConfig()).getActionMonitorCollector().log(pageContext, 'query', 'Query', executionTime, queryResult)" lock: call: "((ConfigWebPro)pc.getConfig()).getActionMonitorCollector().log(pageContext, 'lock', 'Lock', executionTime, lockName + ':' + timeoutInMillis)" mail: call: "((ConfigWebPro)config).getActionMonitorCollector().log(config, 'mail', 'Mail', executionTime, properties)" cache: "Cache operations" methods: log_request: signature: "void log(PageContext pc, String type, String label, long executionTime, Object data)" context: "Within HTTP request" parameters: pc: "Current page context" type: "Operation type (query, lock, mail, etc.)" label: "Operation label" executionTime: "Duration in milliseconds" data: "Operation-specific data" log_background: signature: "void log(ConfigWeb config, String type, String label, long executionTime, Object data)" context: "Outside HTTP request context" parameters: config: "Web configuration" type: "Operation type" label: "Operation label" executionTime: "Duration in milliseconds" data: "Operation-specific data" get_data: signature: "Query getData(Map arguments)" purpose: "Return collected data for reporting" arguments: startDate: "Date filter" endDate: "Date filter" type: "String filter for operation type" request: interface: "lucee.runtime.monitor.RequestMonitor" base_interface: "lucee.runtime.monitor.Monitor" trigger: "End of each HTTP request" thread_context: "Request processing thread" async_support: true methods: log: signature: "void log(PageContext pc, boolean error)" timing: "Called at request completion" parameters: pc: "Page context with request data" error: "True if request resulted in error" get_data: signature: "Query getData(ConfigWeb config, Map arguments)" scope: "Single web context data" arguments: startDate: "Date filter" endDate: "Date filter" errorOnly: "Boolean filter for error requests" interval: interface: "lucee.runtime.monitor.IntervallMonitor" base_interface: "lucee.runtime.monitor.Monitor" trigger: "Timer-based (default 5000ms)" thread_context: "Dedicated interval monitoring thread" request_context: false methods: log: signature: "void log()" timing: "Called at regular intervals" context: "No PageContext available" get_data: signature: "Query getData(Map arguments)" scope: "System-wide interval data" arguments: startDate: "Date filter" endDate: "Date filter" base_interface: interface: "lucee.runtime.monitor.Monitor" methods: init: signature: "void init(ConfigWeb config, String name, Map arguments)" timing: "Called after instantiation" parameters: config: "Web configuration instance" name: "Monitor name from configuration" arguments: "Additional configuration parameters" get_name: signature: "String getName()" purpose: "Return monitor identifier" is_enabled: signature: "boolean isEnabled()" purpose: "Runtime enable/disable check" implementation_details: loading_method: "ConfigFactoryImpl.loadMonitors()" loading_context: "Server configuration initialization" constructor_resolution: with_config: signature: "public ClassName(ConfigServer configServer)" detection: "Reflector.getConstructorInstance()" default: signature: "public ClassName()" fallback: "ClassUtil.newInstance(clazz)" wrapper_classes: action: "ActionMonitorWrap for non-ActionMonitor objects" request: "RequestMonitorWrap for non-RequestMonitor objects" interval: "IntervallMonitorWrap for non-IntervallMonitor objects" async_implementation: wrapper: "AsyncRequestMonitor" condition: "async=true in configuration" execution: "Background thread execution" storage: action_monitors: collector: "ActionMonitorCollector" factory: "ActionMonitorFactory.getActionMonitorCollector()" storage_method: "configServer.setActionMonitorCollector()" access: "((ConfigWebPro)config).getActionMonitorCollector()" request_monitors: type: "RequestMonitor[] array" storage_method: "configServer.setRequestMonitors()" wrapper: "RequestMonitorProImpl" interval_monitors: type: "IntervallMonitor[] array" storage_method: "configServer.setIntervallMonitors()" cfml_integration: functions: get_monitor_data: signature: "getMonitorData(String type, Struct arguments)" types: ["action", "request", "interval"] return_type: "Query" implementation: "Calls monitor.getData(arguments)" get_monitoring_info: signature: "getMonitoringInfo()" return_type: "Struct" purpose: "Monitor configuration and status" error_handling: monitor_failure: logging: "LogUtil.logGlobal(config, Log.LEVEL_INFO, class, message)" continuation: "Processing continues with remaining monitors" runtime_exceptions: action_monitors: "Log error, continue operation" request_monitors: "Log error, continue request processing" interval_monitors: "Log error, continue interval cycle" threading: action_monitors: execution: "Synchronous in operation thread" performance_impact: "Direct impact on operation timing" recommendations: "Keep implementations lightweight" request_monitors: synchronous: execution: "End of request thread" blocking: "Delays request completion" asynchronous: wrapper: "AsyncRequestMonitor" execution: "Background thread pool" impact: "No request delay" interval_monitors: thread: "Dedicated system monitoring thread" isolation: "Separate from request processing" interval: "5000ms default" type_constants: action: "Monitor.TYPE_ACTION" request: "IntervallMonitor.TYPE_REQUEST" interval: "IntervallMonitor.TYPE_INTERVAL" class_definitions: resolution_order: "OSGi bundle > Maven > Standard classpath" loading: "ClassDefinition.getClazz()" formats: osgi: bundleName: "OSGi symbolic name" bundleVersion: "OSGi version format" maven: coordinates: "groupId:artifactId:version" simple: class: "Full class name only" logging: monitor_loading: level: "INFO" method: "LogUtil.logGlobal()" message: "loaded {type} monitor [{className}]" monitor_initialization: level: "INFO" method: "LogUtil.logGlobal()" message: "initialize {type} monitor [{className}]" runtime_errors: method: "LogUtil.logGlobal(config, className, throwable)" level: "ERROR" dependencies: required: - name: "lucee-core" classes: - "lucee.runtime.monitor.*" - "lucee.runtime.config.ConfigWeb" - "lucee.runtime.PageContext" - "lucee.runtime.type.Query" optional: - name: "osgi-framework" purpose: "Bundle class loading" - name: "servlet-api" purpose: "HTTP request monitoring"