6

I need to find, in ApexLogs raw bodies, references to a given String value.

I know we can query the object ApexLog fields, by using the following code:

SELECT id, 
       loguserid, 
       loglength, 
       lastmodifieddate, 
       request, 
       operation, 
       application, 
       status,
       durationmilliseconds, 
       systemmodstamp, 
       starttime, 
       location 
FROM   apexlog 

And, once we have the log ID, we can either retrieve a raw log, using the REST resource /sobjects/ApexLog/id/Body/ or even the totally not recommended trace download:

https://YourPrefix.salesforce.com/apexdebug/traceDownload.apexp?id=99999999999999YourID

Now, is it possible to query Debug Logs Bodies, directly, using a WHERE clause, to find a string reference? In which object the debug body is stored?

Thanks!

0

3 Answers 3

3

It's in ApexLog, but you can't query/filter the log itself, only the exposed metadata (e.g. status or request). You would necessarily need to download each one using the preferred API (/sobjects/ApexLog/{id}/Body). This limitation exists because you can't filter on the logs. You also cannot search (SOSL) on ApexLog, either, probably as a matter of performance.

0
7

You don't name a use case, or whether there is a particular place you are integrating this from. But if it was just a matter of, "I need to get a log out and check for some string value in it," these days, I would probably prefer to use Salesforce DX to do this.

sfdx force:apex:log:get -i <MyLogId>

Using this you can also retrieve multiple logs at once...potentially all of them.

sfdx force:apex:log:get -n 2  <- retrieve the last 2 log files
sfdx force:apex:log:get -n 10 

This will spit out all of the log bodies which you can then grep.

sfdx force:apex:log:get -n 2 | grep 'Colonial'

18:46:16.10 (20641304)|VARIABLE_ASSIGNMENT|[2]|p|{"Id":"a040E000001zVStQAM","Name":"Stunning Colonial","Location__c":"API location: [42.360642 -71.110448]"}|0x5cacdf1b
18:46:35.11 (17502936)|VARIABLE_ASSIGNMENT|[2]|p|{"Id":"a040E000001zVStQAM","Name":"Stunning Colonial","Location__c":"API location: [42.360642 -71.110448]"}|0x37955bc2

If you want context around the actual line you find, you can use grep's before and after context features to get more than just the line you are looking for. For instance here, I get the line with the regex pattern, and 5 lines before and after each time it is found.

sfdx force:apex:log:get -n 2 | grep -B 5 -A 5 'Colonial'

18:46:35.11 (17280734)|STATEMENT_EXECUTE|[2]
18:46:35.11 (17333161)|USER_DEBUG[2]|DEBUG|System.Location[getLatitude=42.335435;getLongitude=-71.106827;]
18:46:35.11 (17362725)|HEAP_ALLOCATE|[2]|Bytes:5
18:46:35.11 (17384098)|HEAP_ALLOCATE|[2]|Bytes:16
18:46:35.11 (17396491)|VARIABLE_SCOPE_BEGIN|[2]|p|Property__c|true|false
18:46:35.11 (17502936)|VARIABLE_ASSIGNMENT|[2]|p|{"Id":"a040E000001zVStQAM","Name":"Stunning Colonial","Location__c":"API location: [42.360642 -71.110448]"}|0x37955bc2
18:46:35.11 (17517639)|STATEMENT_EXECUTE|[2]
18:46:35.11 (17520423)|STATEMENT_EXECUTE|[2]
18:46:35.11 (17566892)|USER_DEBUG|[2]|DEBUG|System.Location[getLatitude=42.360642;getLongitude=-71.110448;]
18:46:35.11 (17597445)|HEAP_ALLOCATE|[2]|Bytes:5
18:46:35.11 (17616068)|HEAP_ALLOCATE|[2]|Bytes:16
--
--
18:56:25.19 (29745072)|STATEMENT_EXECUTE|[2]
18:56:25.19 (29815343)|USER_DEBUG|[2]|DEBUG|System.Location[getLatitude=42.335435;getLongitude=-71.106827;]
18:56:25.19 (29877304)|HEAP_ALLOCATE|[2]|Bytes:5
18:56:25.19 (29908067)|HEAP_ALLOCATE|[2]|Bytes:16
18:56:25.19 (29923611)|VARIABLE_SCOPE_BEGIN|[2]|p|Property__c|true|false
18:56:25.19 (30106839)|VARIABLE_ASSIGNMENT|[2]|p|{"Id":"a040E000001zVStQAM","Name":"Stunning Colonial","Location__c":"API location: [42.360642 -71.110448]"}|0x380f42d
18:56:25.19 (30131234)|STATEMENT_EXECUTE|[2]
18:56:25.19 (30135912)|STATEMENT_EXECUTE|[2]
18:56:25.19 (30215204)|USER_DEBUG|[2]|DEBUG|System.Location[getLatitude=42.360642;getLongitude=-71.110448;]
18:56:25.19 (30269076)|HEAP_ALLOCATE|[2]|Bytes:5
18:56:25.19 (30294622)|HEAP_ALLOCATE|[2]|Bytes:16
0
1

The following simple apex code will provide the log body, without using the tooling api callout:

string logId = '{alexlog_id}';
PageReference pageRef = new PageReference('/servlet/servlet.FileDownload?file='+logId);
string logBody = String.valueOf(pageRef.getContent());
system.debug(logBody);

I know it's crazy - but it works!

1
  • Hi Yo Force, but in this case you already have the logId, correct? May 26, 2021 at 22:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .