+ Start a Discussion
PolyglotPolyglot 

Execute Anonymous through the Tooling REST API

I'm writing an IDE plugin and I prefer using the REST API.  For the Execute Anonymous resource:

http://domain/services/data/vXX.X/tooling/executeAnonymous/?anonymousBody=System.debug('Hello World');

The response is:

{"exceptionMessage":null,"compileProblem":null,"compiled":true,"exceptionStackTrace":null,"column":-1,"line":-1,"success":true}

How do I get access to the output/debug log?
Ashish_SFDCAshish_SFDC
Hi, 

To execute anonymous Apex:
req.setEndpoint('http://na1.salesforce.com/services/data/v28.0/tooling/executeAnonymous/?
anonymousBody=System.debug('Test')%3B');
req.setMethod('GET');


/sobjects/ApexLog/id/Body/
GET
Retrieves a raw debug log by ID. Available from API version 28.0 or later.

http://www.salesforce.com/us/developer/docs/api_tooling/Content/intro_rest_overview.htm


Regards,
Ashish
PolyglotPolyglot
Thank you for your reply.  Where do I get the ID from when I call the /sobjects/ApexLog/id/Body?  This isn't returned from the Execute Anonymous call.
Ashish_SFDCAshish_SFDC
Hi , 


If we supply the ID of the class then we get the raw debug log. 


Regards,
Ashish
PolyglotPolyglot
Id of the class?  hun?

The execute anonymous resource I'm invoking is: http://domain/services/data/vXX.X/tooling/executeAnonymous/?anonymousBody=System.debug('Hello World');

There is no Apex class involved - other than System.  Does System have an Id?
Ashish_SFDCAshish_SFDC
Hi , 


Did you try this, 

req.setEndpoint('http://na1.salesforce.com/services/data/v29.0/tooling/executeAnonymous/?anonymousBody=System.debug('Hello World');
req.setMethod('GET');

Replace the na1 with the server of your Org. 


Regards,
Ashish
John Aaron NelsonJohn Aaron Nelson
Please refer to http://blog.lkatney.com/2015/09/10/running-apex-code-through-executeanonymous-api/

As I mentioned above, there is no straight forward way to do this in REST API. This can be done in 4 Steps:

Set Trace Flag : To log logs against your user

Endpoint : /services/data/v34.0/tooling/sobjects/traceFlag Method : POST Post: { "ApexCode": "Finest", "ApexProfiling": "Error", "Callout": "Error", "Database": "Error", "ExpirationDate": "2015-09-11", "TracedEntityId": "00590000000tQBwAAM", "Validation": "Error", "Visualforce": "Error", "Workflow": "Error", "ScopeId": null, "System": "Error" }

To know more about Trace Flag, go through this documentatation.

Run your executeAnonymous call through API.

Then, We need to make a query to get Id of raw log from ApexLog table. Run below query to get last log from user.

SELECT Id FROM ApexLog WHERE Request = 'API' AND Location = 'Monitoring' AND Operation like '%executeAnonymous%' AND LogUserId='00590000000tQBwAAM' ORDER BY StartTime DESC, Id DESC LIMIT 1

After getting Id, We need to make an another call for raw logs.

Endpoint: /services/data/v29.0/sobjects/ApexLog/07L9000004qMsoiEAC/Body Method: GET

(Optional) Remove trace flags from visibility.
Ken Koellner 7Ken Koellner 7
I've been trying to do this with the SOAP API and haven't found an easy answer.  I actually watched the network traffic when running the Dev Console and doing an execute anonymous to see if I could reverse engineer it.  It looks like the response from execute anonymous does not identify the debug log or contain the log.  The Dev Console is doing cometd polling for debug logs and I see it get an Id.  Then it does they query specifically for the Id of the latest log.  I wonder if it uses the same heurstistic of latest log for the user.  In theory, you could have a race condition with another process and get the wrong log but maybe that chance of that is so small, it's not to worry about.

-Ken