2015-08-16

ExecuteAnonymousによるデバッグログの取得

Salesforceで検証用途等で任意のコードを実行させたい場合は、ExecuteAnonymousのAPIを使うことになりますが、SOAP APIだとHTTPリクエストのボディを以下のようにして呼び出すことが出来ます。

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.body/org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <env:Header>
    <SessionHeader xmlns="http://soap.sforce.com/2006/08/apex">
      <sessionId>*******</sessionId>
    </SessionHeader>
  </env:Header>
  <env:Body>
    <executeAnonymous xmlns="http://soap.sforce.com/2006/08/apex">
      <String>System.debug('test!!!');</String>
    </executeAnonymous>
  </env:Body>
</env:Envelope>

これだと、EclipseのExecute Anonymousのように実行結果としてのデバッグログが出せず、コンパイル結果、実行結果、エラーメッセージしか出力されません。 デバッグログを出力するには、SOAPヘッダにDebuggingHeaderを付与する必要があります。

<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.body/org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <env:Header>
    <DebuggingHeader xmlns="http://soap.sforce.com/2006/08/apex">
      <categories>
        <category>Apex_code</category>
        <level>FINEST</level>
      </categories>
    </DebuggingHeader>
    <SessionHeader xmlns="http://soap.sforce.com/2006/08/apex">
      <sessionId>********</sessionId>
    </SessionHeader>
  </env:Header>
  <env:Body>
    <executeAnonymous xmlns="http://soap.sforce.com/2006/08/apex">
      <String>System.debug('test!!!');</String>
    </executeAnonymous>
  </env:Body>
</env:Envelope>

レスポンスはこんな感じになります。

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/08/apex" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <soapenv:Header>
    <DebuggingInfo>
      <debugLog>33.0 APEX_CODE,FINEST
        Execute Anonymous: System.debug('test!!!');
        12:01:49.057 (57868466)|EXECUTION_STARTED
        12:01:49.057 (57878694)|CODE_UNIT_STARTED|[EXTERNAL]|execute_anonymous_apex
        12:01:49.058 (58014087)|HEAP_ALLOCATE|[71]|Bytes:3
        12:01:49.058 (58051816)|HEAP_ALLOCATE|[76]|Bytes:152
        12:01:49.058 (58071605)|HEAP_ALLOCATE|[272]|Bytes:408
        12:01:49.058 (58094489)|HEAP_ALLOCATE|[285]|Bytes:408
        12:01:49.058 (58131902)|HEAP_ALLOCATE|[379]|Bytes:48
        12:01:49.058 (58167202)|HEAP_ALLOCATE|[131]|Bytes:6
        12:01:49.058 (58216079)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:1
        12:01:49.058 (58304318)|STATEMENT_EXECUTE|[1]
        12:01:49.058 (58310421)|STATEMENT_EXECUTE|[1]
        12:01:49.058 (58314726)|HEAP_ALLOCATE|[1]|Bytes:7
        12:01:49.058 (58347854)|HEAP_ALLOCATE|[50]|Bytes:5
        12:01:49.058 (58369922)|HEAP_ALLOCATE|[56]|Bytes:5
        12:01:49.058 (58380645)|HEAP_ALLOCATE|[63]|Bytes:7
        12:01:49.058 (58456193)|USER_DEBUG|[1]|DEBUG|test!!!
        12:01:49.058 (58491413)|CODE_UNIT_FINISHED|execute_anonymous_apex
        12:01:49.059 (59804344)|EXECUTION_FINISHED
      </debugLog>
    </DebuggingInfo>
  </soapenv:Header>
  <soapenv:Body>
    <executeAnonymousResponse>
      <result>
        <column>-1</column>
        <compileProblem xsi:nil="true"/>
        <compiled>true</compiled>
        <exceptionMessage xsi:nil="true"/>
        <exceptionStackTrace xsi:nil="true"/>
        <line>-1</line>
        <success>true</success>
      </result>
    </executeAnonymousResponse>
  </soapenv:Body>
</soapenv:Envelope>

categoryやlevelでデバッグログの種類と内容を確定します。リファレンスは以下になります。 DebuggingHeader | Force.com Apex Code Developer’s Guide | Salesforce Developers

上記SOAPメッセージはSalesforceの「開発>API」のApex WSDLで取得できるexecuteAnonymousなのですが、Toolingに定義されているexecuteAnonymousではデバッグログは取得できませんでした。

ちなみに、C#だと以下のようなコードになります。

Partner.SforceService ss = new Partner.SforceService();
Partner.LoginResult lr = ss.login("hoge@example.com", "password");

Apex.ApexService apexs = new Apex.ApexService();
apexs.SessionHeaderValue = new Apex.SessionHeader();
apexs.SessionHeaderValue.sessionId = lr.sessionId;
apexs.DebuggingHeaderValue = new Apex.DebuggingHeader();
apexs.DebuggingHeaderValue.categories = new Apex.LogInfo[1];
apexs.DebuggingHeaderValue.categories[0] = new Apex.LogInfo();
apexs.DebuggingHeaderValue.categories[0].level = Apex.LogCategoryLevel.Finest;
apexs.DebuggingHeaderValue.categories[0].category = Apex.LogCategory.Apex_code;

apexs.executeAnonymous("System.debug('abcde!!');");

Apex WSDL内にはloginコールが含まれていないので、Partner WSDL等でloginコールをしてsessionIdを取得して、Apex WSDLのスタブのsessionIdとしてセットする感じになります。

このエントリーをはてなブックマークに追加