Idea Summary
The built-in activity log, APEX_WORKSPACE_ACTIVITY_LOG, is perfectly suited for most use cases, and it would be entirely OK to leave it as is. However, in certain scenarios - particularly those governed by stringent security auditing requirements and regulatory compliance - more granular logging becomes necessary. This is especially true when business data flows from the server to the client. In such cases, either extend the current activity log or developers should have the ability to implement and populate their own custom, detailed logging mechanism. Addressing this idea would unlock the full potential of APEX's native components for use in highly regulated environments.
Use Case
In a strictly regulated environment, it is essential to log every server-side access to business data objects (Infotypes) with the following details:
LOG_TIMESTAMP
APEX_USER
APPLICATION_ID
PAGE_ID
[...] and several other attributes that can already be captured reliably using existing capabilities.
However, the following information is currently missing and would be critical for compliance:
STATIC_ID : The static ID of the component (which could be mapped by developers to a logical business data object or Infotype for logging purposes, rather than logging the raw static ID itself).
ACTION : Indicates what the component is doing with "our" business data. Actions unrelated to business data - such as saving user-specific preferences or personal report settings - can be excluded. Of interest are actions that involve retrieving or exporting business data, such as fetchData or download.
ROW_COUNT : The number of data rows transmitted to the browser. For fetchData actions, this reflects the number of rows inserted into or initially displayed in a list in the browser. For download actions, it represents the number of rows included in the downloaded file.
TOTAL_ROW_COUNT : Where applicable, configured, and actually determined by the component (e.g. in components with activated Total Row Count), this field should contain the total number of rows exactly as displayed in the browser, with applied current filtering. If not applicable or not determined, it should remain empty.
FILTER : For fetchData or download-prepare-file actions, this should be a CLOB containing a string representation of the applied filters. For example:
- In Classic Reports with Faceted Search: the search items and their values,
- In LOVs: the search text entered by the user,
- In Interactive Reports or Interactive Grids: the active filters, e.g., in a format like Column_A EQ Value_1 (and) Column_B BETWEEN Value_2 AND Value_3 (and) RowFilter = Value_4
The exact formatting and level of detail may vary by use case, but access to the raw filter data is essential.
FILE_NAME : For download-get-file actions, this should contain the name of the downloaded file; otherwise empty.
One such log record each time any of the following occurs:
- The user initially views a list in an CR/IR/IG/LOV/TREE.., refreshes the list, switches reports, changes filters, or navigates to another pagination-page (when pagination is set to "Page" mode).
- With infinite scrolling enabled: on every server request that retrieves additional data.
- When the component calls the server to prepare a file for subsequent download.
- When the component initiates the actual download of a (previously prepared) file.
- This logging capability must also support scenarios involving multiple components per request. For example: In a page-rendering request, if two Classic Reports are placed on the same page and both load their data immediately (without lazy loading), two separate log records should be created
Without this fine-grained, component-level logging, the application would not receive approval to operate.