🔖 Document Audit and Record Change Tracking
GermainUX Document Audit records changes to structured business records as time-stamped events, providing a near-real-time history of what changed, when it changed, who made the change and which field was affected. In this context, a document is a structured record or object snapshot—not necessarily a file—such as a service request, ticket, order, opportunity, customer record or configuration object.
Document Audit helps organizations monitor data changes, measure how long records remain in each status and connect those changes with business processes, users and application activity. Effective audit controls should focus on stable record identifiers, targeted field selection, consistent timestamp and author attribution, secure data-source access, and rules that convert only relevant changes into events, KPIs, alerts or reports.
To maintain reliable audit visibility, organizations should minimize unnecessary data collection, mask or exclude sensitive values, restrict access to audit history, define retention expectations and validate that generated changes align with the intended business process and compliance requirements.
🎯 Business Outcomes
GermainUX Document Audit helps organizations:
|
Outcome |
|---|
|
Maintain a searchable history of record and field changes. |
|
Identify who changed a record and when the change occurred. |
|
Compare current and previous values. |
|
Measure how long records remain in a status or process stage. |
|
Detect delayed, unexpected or unauthorized changes. |
|
Analyze ticket, request, order and workflow progression. |
|
Turn selected changes into GermainUX events, KPIs, alerts and reports. |
|
Correlate data changes with user sessions, application transactions and business outcomes. |
🛠 Common Use Cases
📄 Data Audit Trail
Document Audit tracks changes to structured data maintained in external systems. GermainUX can retrieve or receive record updates through supported sources such as SQL queries, REST APIs, SOAP services, browser monitoring and other integrations.
Examples include:
|
Example |
|---|
|
Service-request status, priority or ownership changes |
|
Opportunity stage and amount changes |
|
Order, inventory or fulfillment updates |
|
Ticket assignment and resolution changes |
|
Customer, account or profile updates |
|
Configuration and metadata changes |
⏱ Status-Duration Tracking
By recording each status transition, GermainUX can calculate how long a record remains in a particular state.
Examples include:
|
Metric |
|---|
|
Time before a ticket receives its first response |
|
Time spent waiting for approval |
|
Service-request resolution time |
|
Duration of each order-fulfillment stage |
|
Time an opportunity remains in a sales stage |
|
Process bottlenecks and SLA violations |
⚙️ How Document Audit Works
The audit workflow has three main stages:
|
Stage |
|---|
|
A monitoring component creates a |
|
The Document Service compares that update with the previously stored state. |
|
For each detected field change, the service produces a |
External record or application
↓
DocumentUpdate
↓
Document Service: compare and store state
↓
DocumentChange
↓
Rule → Event, KPI, alert, report or automation
The exact behavior depends on the monitoring component, document identifiers, field paths, rules and storage configuration.
📂 Core Data Types
➡️ DocumentUpdate
A DocumentUpdate describes the latest state—or a partial update—of a tracked record.
Important fields include:
|
Field |
Purpose |
|---|---|
|
|
Stable identifier for the tracked record |
|
|
Logical record type, such as |
|
|
User or system associated with the update |
|
|
Time associated with the update |
|
|
Searchable properties describing the record |
|
Field paths and values |
Current values to compare with the stored document state |
📝 DocumentChange
A DocumentChange represents a field-level difference detected by the Document Service.
Important fields include:
|
Field |
Purpose |
|---|---|
|
|
Identifier of the changed record |
|
|
Logical record type |
|
|
Path of the field that changed |
|
|
Previous value |
|
|
New value |
|
|
User or system associated with the change |
|
|
Time when the change event was created |
|
|
Context describing the record |
|
|
Context describing the specific change |
🔧 Configuration Overview
To configure Document Audit:
|
Step |
|---|
|
Identify the record type and stable identifier. |
|
Select the fields and metadata to monitor. |
|
Configure a source to create |
|
Send updates to the Document Service. |
|
Configure a rule to process the resulting |
|
Convert relevant changes into GermainUX facts or events. |
|
Create the required KPIs, dashboards, alerts or process analytics. |
Avoid using mutable values as documentId. The identifier must consistently represent the same business record across updates.
📥 Process DocumentChange Outputs
The Document Service outputs DocumentChange events when it detects differences between the incoming update and the stored record state.
Customize the document-audit-default rule or create a dedicated rule for the monitored record type.
In the Configuration Console, set:
germain.apm.documentAudit.rule
to either:
document-audit-default
or the name of the custom rule.
💡 Example: Siebel Service Request Status Change
The following rule processes status changes for Siebel Service Requests and creates a GermainUX GenericEvent.
package com.germainsoftware.apm.analytics.audit;
dialect "mvel"
import com.germainsoftware.apm.data.model.*;
import com.germainsoftware.apm.storage.documentAudit.DocumentChange;
import java.time.*;
global org.slf4j.Logger logger;
global com.germainsoftware.apm.storage.StorageService storage;
rule "Siebel Service Request Rule"
when
$update : DocumentChange(
documentType == "Siebel SR",
path == "status"
)
then
logger.info("SR Change: {}", $update.value);
// Create a new Service Request status-change event.
GenericEvent ev = new GenericEvent();
ev.name = $update.documentType;
ev.type = "Siebel:SR Change";
ev.timestamp = $update.timeCreated;
ev.businessObject = $update.value;
ev.sequence = $update.documentId;
storage.insertFact(ev);
retract($update);
end
This example stores the new status in businessObject and uses the Service Request document ID as the event sequence. Adapt the event fields to the KPI and analysis required by your environment.
🗄️ DocumentChange Schema
class DocumentChange {
String documentId;
String documentType;
Map<String, String> documentMetadata;
ValueMap documentBody;
OffsetDateTime timeCreated;
Map<String, String> metadata;
String author;
String path;
Object value;
Object oldValue;
}
🚀 Generate DocumentUpdate Inputs from the Engine
Monitoring components such as QueryMonitor can retrieve records and use a rule to create DocumentUpdate objects.
🔍 Example: Query Siebel Service Requests
select
LAST_UPD,
ROW_ID,
CREATED,
CREATED_BY,
LAST_UPD_BY,
SR_NUM,
SR_PRIO_CD,
SR_SEV_CD,
SR_STAT_ID,
SR_TITLE
from SIEBEL.S_SRV_REQ
where LAST_UPD > ?
order by LAST_UPD asc
The query retrieves Service Requests changed since the last monitored timestamp.
🔁 Example: Convert the Query Result to DocumentUpdate
import java.util.Calendar;
import java.util.regex.*;
import java.time.*;
import java.time.temporal.*;
import com.germainsoftware.apm.config.data.*;
import com.germainsoftware.apm.converter.*;
import com.germainsoftware.apm.data.model.*;
import com.germainsoftware.apm.data.indexer.*;
import com.germainsoftware.apm.message.*;
import com.germainsoftware.apm.model.*;
import com.germainsoftware.apm.router.*;
global org.slf4j.Logger logger;
global com.germainsoftware.apm.converter.DatamartConverter datamart;
global com.germainsoftware.apm.router.RouterContext context;
rule "Siebel SR"
when
$msg : QueryResultMessage(category == "Siebel SR")
then
DocumentUpdate doc = new DocumentUpdate(
$msg.getString(1), // ROW_ID: stable document identifier
"Siebel SR", // Document type
$msg.getString(4) // LAST_UPD_BY: author
);
doc.timestamp = $msg.getTimestamp(0); // LAST_UPD
doc.set("created", $msg.getTimestamp(2).toString()); // CREATED
doc.set("createdBy", $msg.getString(3)); // CREATED_BY
doc.set("number", $msg.getString(5)); // SR_NUM
doc.set("priority", $msg.getString(6)); // SR_PRIO_CD
doc.set("severity", $msg.getString(7)); // SR_SEV_CD
doc.set("status", $msg.getString(8)); // SR_STAT_ID
doc.set("title", $msg.getString(9)); // SR_TITLE
Queues.postDocumentUpdate(doc);
retract($msg);
end
The array indexes in this rule depend on the order of columns in the SQL query. If the query changes, update the indexes and field mapping together.
⚙️ DocumentUpdate API Schema
The following is a simplified schema for reference; it is not intended to be copied as a compilable Java interface.
interface DocumentUpdate {
DocumentUpdate(
String documentId,
String documentType,
String author
);
OffsetDateTime timestamp;
// Searchable properties describing the document.
HashMap<String, String> documentMetadata;
// Add metadata describing this update.
void addAttribute(String attributeName, String value);
// Set a document field. Nested paths use dot notation:
// child.grandchild.greatgrandchild
void set(String path, @Nullable Object value);
// Remove a field from the document.
void deletePath(String path);
}
🌐 Generate DocumentUpdate Inputs from Web UX
A Web UX Monitoring Profile can generate DocumentUpdate objects from authorized browser-side application activity.
Customize the profile’s initScript and add the update to the Document Audit queue:
BOOMR.utils.addToDocumentAuditQueue(update);
type DocumentUpdate = {
documentId: string;
documentType: string;
documentMetadata: Record<string, string>;
timestamp: number;
author: string;
metadata: Record<string, string>;
fieldUpdates: FieldUpdate[];
};
type FieldUpdate = {
path: string;
valueJson: string;
spliceIndex: number;
deleteCount: number;
};
Browser-Side Configuration Considerations
When generating document updates from a monitored user interface:
|
Consideration |
|---|
|
Use a stable record identifier. |
|
Send only fields required for the audit use case. |
|
Avoid collecting passwords, payment data or other unnecessary sensitive content. |
|
Apply masking or exclusion before data is transmitted. |
|
Set timestamps consistently. |
|
Include an author only when collection is authorized. |
|
Test create, update, nested-field and deletion behavior. |
|
Confirm that repeated identical updates do not generate unwanted change noise. |
🕐 Track Status Duration
To measure how long a record remains in a status:
|
Step |
|---|
|
Generate a |
|
Convert the resulting |
|
Use the stable document ID to order events for the same record. |
|
Calculate the duration between consecutive status events. |
|
Define KPIs and SLAs for expected status duration. |
Status analysis can then be segmented by record type, priority, owner, team, application, customer or other captured metadata.
📈 Analytics, Alerts and Automation
Document Audit events can support:
|
Capability |
|---|
|
Audit-history dashboards |
|
Field-change frequency and trends |
|
Status-duration and aging reports |
|
Detection of unexpected or prohibited changes |
|
SLA alerts for records remaining too long in a status |
|
Correlation with user sessions and application transactions |
|
Business-process and workflow analysis |
|
Approved follow-up or remediation workflows |
Rules should create only the analytical events required by the use case to avoid unnecessary data volume and noise.
🔒 Security and Data Governance
Document Audit can collect sensitive business and personal data. Configure it according to the organization’s security, privacy, retention and access requirements.
Recommended controls include:
|
Control |
|---|
|
Monitor only required record types and fields. |
|
Mask, anonymize or exclude sensitive values. |
|
Restrict audit-history access to authorized roles. |
|
Define retention requirements for document state and change events. |
|
Protect credentials used by SQL, REST, SOAP and other data sources. |
|
Validate author attribution and timestamp accuracy. |
|
Document the rules that convert changes into alerts or automated actions. |
Document Audit provides application-level change visibility; whether it satisfies a particular legal or regulatory audit requirement depends on the organization’s configuration, controls and governance.
🔧 Troubleshooting
If expected changes are not appearing:
|
Check |
|---|
|
Confirm that the source is producing |
|
Verify that |
|
Check the field path and incoming value. |
|
Confirm that updates are reaching the Document Service. |
|
Verify the |
|
Confirm that the rule matches the expected |
|
Review rule execution and storage logs. |
|
Verify that the generated event is supported by the intended KPI and dashboard. |
ℹ️ Get Help
The Germain Team can help you set this up. Contact GermainUX Support.
Service: Analytics
Feature Availability: 2022.1 or later