プログラマ38の日記

主にプログラムメモです。

Salesforce: Batch Apexでビッグオブジェクト(BigOBject)に設定変更履歴エントリを蓄積してみた

f:id:crmprogrammer38:20190101140331p:plain

ビッグオブジェクトの調査をしてみて、更新・削除が頻繁に行われるデータよりはログデータのような一度作成したら更新のかからないデータを保存するのに向いているようです。

 

Salesforceでそういった特性のデータは、項目変更履歴(・・・History)や、イベントログファイル(EventLogFile)、設定変更履歴エントリ(SetupAuditTrail)などがあると思います。

項目変更履歴は標準ビッグオブジェクトが用意されているみたいなのでパス、イベントログファイルは、ログファイルのCSVを分解する必要があってお試しで作るにはボリュームがあるのでパス、ということで設定変更履歴エントリで試してみました。

 

オブジェクトを作成する

次の内容で「SetupAuditTrail__b.object」ファイルを用意しdeployする。
deploy後、プロファイルでオブジェクト権限や項目レベルセキュリティを設定する。

<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <deploymentStatus>Deployed</deploymentStatus>
    <fields>
        <fullName>Id__c</fullName>
        <label>Salesforce ID</label>
        <length>18</length>
        <required>true</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>
    <fields>
        <fullName>Action__c</fullName>
        <label>アクション</label>
        <length>150</length>
        <required>false</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>
    <fields>
        <fullName>Section__c</fullName>
        <label>セクション</label>
        <length>18</length>
        <required>false</required>
        <type>Text</type>
        <unique>false</unique>
    </fields>
    <fields>
        <fullName>CreatedDate__c</fullName>
        <label>エントリ作成日</label>
        <required>false</required>
        <type>DateTime</type>
        <unique>false</unique>
    </fields>
    <fields>
        <fullName>CreatedById__c</fullName>
        <externalId>false</externalId>
        <label>エントリ作成者</label>
        <referenceTo>User</referenceTo>
        <relationshipName>B_SetupAuditTrails</relationshipName>
        <required>false</required>
        <type>Lookup</type>
    </fields>
    <fields>
        <fullName>Display__c</fullName>
        <label>表示</label>
        <visibleLines>3</visibleLines>
        <length>1000</length>
        <required>false</required>
        <type>LongTextArea</type>
    </fields>
    <fields>
        <fullName>DelegateUser__c</fullName>
        <label>代理ユーザ</label>
        <length>80</length>
        <required>false</required>
        <type>Text</type>
    </fields>
    <fields>
        <fullName>ResponsibleNamespacePrefix__c</fullName>
        <label>ソースの名前空間プレフィックス</label>
        <length>15</length>
        <required>false</required>
        <type>Text</type>
    </fields>
    <indexes>
        <fullName>B_SetupAuditTrailIndex</fullName>
        <label>設定変更履歴エントリインデックス</label>
        <fields>
            <name>Id__c</name>
            <sortDirection>ASC</sortDirection>
        </fields>
    </indexes>
    <label>(BigObject)設定変更履歴エントリ</label>
</CustomObject>

バッチApexを作成する

次の内容で「Batch_StoreSetupAuditTrail」クラスを作成しスケジュール設定する。

global class Batch_StoreSetupAuditTrail implements Database.Batchable<Sobject> , Schedulable {

    global void execute(SchedulableContext ctx){
        Database.executebatch(new Batch_StoreSetupAuditTrail(), 200);
    }


    // The batch job starts
    global Database.Querylocator    start(Database.BatchableContext bc){
        return Database.getQuerylocator(    
            [Select
                 Id
                ,Action
                ,Section
                ,CreatedDate
                ,CreatedById
                ,Display
                ,DelegateUser
                ,ResponsibleNamespacePrefix
            From
                 SetupAuditTrail
            where CreatedDate = LAST_MONTH]
        );
    }
  
    // The batch job executes and operates on one batch of records
    global void execute(Database.BatchableContext bc, List<Sobject> scope){
  
        if(scope == null || scope.isEmpty() ){
            return;
        }
        
        List<SetupAuditTrail__b> b_rows = new List<SetupAuditTrail__b>();
        for(Sobject row : scope){
            SetupAuditTrail audit = (SetupAuditTrail)row;
            
            SetupAuditTrail__b b_row = new SetupAuditTrail__b();
            b_row.Id__c                          =audit.Id;
            b_row.Action__c                      =audit.Action;
            b_row.Section__c                     =audit.Section;
            b_row.CreatedDate__c                 =audit.CreatedDate;
            b_row.CreatedById__c                 =audit.CreatedById;
            b_row.Display__c                     =audit.Display;
            b_row.DelegateUser__c                =audit.DelegateUser;
            b_row.ResponsibleNamespacePrefix__c  =audit.ResponsibleNamespacePrefix;
            
            b_rows.add(b_row);
        }

        Database.insertImmediate(b_rows);
    }

    // The batch job finishes
    global void finish(Database.BatchableContext bc){
    }
} 

最後に

設定変更履歴エントリは、いつ、だれがどこを変更したかが追跡できて便利ですが、半年より前の履歴は消えてしまいます。そこまで追跡する必要はないかもしれないですが、履歴が残っていれば何かの時の保険として使えます。大人数で長期間で開発する場合、リリース前の最終チェックなどで使ってもいいかもしれません。