2

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!

1

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.

  • Hi Brian, thanks for your help again. Yeah, that's what I've been doing for a while now, in a very boring and inefficient manual process. Guessing the files based on dates, opening one by one, and searching the value manually. Do you happen to know a way to download several log files at once? – Matheus Goncalves May 3 '18 at 18:07
  • @toadgeek I just tried a Composite API, and seems it's not allowed. You might try a Bulk API query, but that seems overly complicated compared to just getting them one at a time. – sfdcfox May 3 '18 at 18:16
2

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
  • Yes, but then you already have the log ID, and that's how you're now able to get the log using the SFDX command. My question is related to one step prior to that: get the ID, based on a String value, querying the log body. – Matheus Goncalves May 3 '18 at 18:01
  • So what do you want to do with the log ID once you have it? – pchittum May 3 '18 at 18:07
  • The important part is not the ID, is the log body. I need to query the log body. – Matheus Goncalves May 3 '18 at 18:33
  • Does it metter that the logs be in different files? – pchittum May 3 '18 at 18:55
  • Yes, unfortunately, that's exactly the problem: I don't know exactly in which file the string value will be. Anyway, thanks for your time and your help. – Matheus Goncalves May 3 '18 at 19:06

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.