3

I want to monitor for inserts and updates on objects over a specified period of time. I don't know in advance which objects I need to monitor. My constraints are the govenor limits and accuracy. I don't want to miss an event. Recording the events doesn't need to be realtime but it does need to be frequent, i.e. every 5 mins.

From researching this problem I appear to have 3 options. I've discounted number 1 due to concerns about governor limits. I'm now debating between 2 and 3. Any thoughts? ANy other options or issues I haven't considered?

  1. Take a snapshot of data at the beginning of the period and compare to latest data using dynamic SOQL. This could get messy if the dataset is large.
  2. Dynamically create triggers on objects of interest via the REST API. Problematic if 1 event is missed - How do I use the Tooling API to create a new Apex Trigger?
  3. Query the history tables for updates and inserts. Not every object has a history table to query.
  • You don't know which objects you'll have to monitor? That makes it impossible - you need to be able to specify a list of objects to watch. Then you can query via SOQL the record's CreatedDate and LastModifiedDate fields. – Mike Chale Oct 15 '13 at 18:00
  • Why do you think it is impossible? I can dynamically interrogate the schema for objects and fields. I can create dynamic SOQL and it looks like I can dynamically create triggers. Not easy but seems feasible. CreatedDate seems like the solution for inserts but I need to monitor updates at the field level. – wisemanIV Oct 15 '13 at 18:09
  • You're right; it is doable given the abilities of dynamic SOQL and whatnot for tracking inserts. Updates will be more challenging but also doable. – Mike Chale Oct 15 '13 at 18:46
3

There is a fourth option. Use the Streaming API. However, I would rule this out due to governor limits.

The best architecture would be trigger based. Every single object needs an after insert and after update trigger. Have your trigger call a generic function similar to:

/**
 * @description Tracks changes in an object for inserts and updates.
 * @param       List<sObject> objs - objects which have changed
 * @param       String tableName   - name of table these objects are a member of
 * @param       String type        - 'insert' | 'update'
 **/
public static void trackChanges(List<sObject> objs, String tableName, String type) {
  List<My_Tracking_Object__c> tracks = new List<My_Tracking_Object__c>();

  for(sObject obj : objs) {
    tracks.add(new My_Tracking_Object__c(
      Record_Changed__c = obj.Id,
      Triggered_By__c   = obj.get('LastModifiedById'),
      Triggered_Date__c = obj.get('LastModifiedDate'),
      Type__c           = type
    ));
  }

  insert tracks;
}

As I type this I realize that this is sort-of a spin on field history tracking which is also a possible way of implementing this.

I guess that is the easy half. The second half is dynamically generating the trigger that calls this helper function. I think that is a bad idea, as now you are going to be unable to create your own custom triggers. If you must, the implementation would probably involve batch/scheduled apex. You can globally describe all sObjects in the org, and as long as their is some common Trigger naming convention, you can use the describe results to determine if an associated trigger exists. If it does not, cast the magic described in this other question: Tooling API usage in salesforce Apex method or use WSDL2Apex on the Apex WSDL.

  • Good point but I've previously discounted using the streaming API for a different reason. Field level tracking is a strong option but I know it is optional and it is off in my dev org by default. Seems risky to base application functionality on this being enabled. Obviously, I could put it in the manual but I'm trying to avoid any setup steps after installing my app. – wisemanIV Oct 15 '13 at 18:36
  • I would be upset if I installed a package that dynamically created triggers on my objects. – Phil Rymek Oct 15 '13 at 18:37
  • Can't the same be said for anything a package does? If the package is tested and doesn't have a detrimental impact on the installation then why not leverage all the tools available? Do you have an alternative? – wisemanIV Oct 15 '13 at 18:45
  • Without proper disclosure, of course. – Mike Chale Oct 15 '13 at 18:47
  • RE: Dynamically creating triggers. The Declarative Rollup Tool I shared recently dynamically creates triggers using the Apex Metadata API (Tooling API may also be an option to explore in future). I agree is not ideal to do this, but it was the only way I could offer such a solution to click admins and so far its gone down very well. As can be seen in the demo video the process is opt-in and there is nothing hidden from them (it even shows the code). andyinthecloud.com/2013/07/07/… – Andrew Fawcett Oct 16 '13 at 8:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.