The new Tooling API has the ApexExecutionOverlayAction
object.
Specifies an Apex code snippet or SOQL query to execute at a specific
line of code in an Apex class or trigger and optionally generate a
heap dump.
You could use this to capture the heap dump for the required user.
Specifically, try setting:
ActionScriptType
to 'None'
ExecutableEntityId
to the Apex class Id
ExpirationDate
to some time in the future. Maybe an hour out
IsDumpingHeap
to true
Iteration
to 1
- The
Line
to "The line number of the heap dump marker"
- the
ScopeId
to the required UserId
I hacked something together in a .NET to try it out.
SforceService toolingService = // Get an instance of the ToolingService
string apexClassId = "01p70000CLASSID";
// This is the session owners UserId
//string heapUserId = "005700000000FOO";
// This is an Id of another user in the Org
string heapUserId = "005700000000BAR";
int heapDumpLine = 27;
ApexExecutionOverlayAction apexExecutionOverlayAction = new SalesforceTooling.ApexExecutionOverlayAction();
apexExecutionOverlayAction.ActionScriptType = "None";
apexExecutionOverlayAction.ExecutableEntityId = apexClassId;
apexExecutionOverlayAction.IsDumpingHeap = true;
apexExecutionOverlayAction.IsDumpingHeapSpecified = true;
apexExecutionOverlayAction.Iteration = 1;
apexExecutionOverlayAction.IterationSpecified = true;
apexExecutionOverlayAction.Line = heapDumpLine;
apexExecutionOverlayAction.LineSpecified = true;
apexExecutionOverlayAction.ScopeId = heapUserId;
SaveResult[] results = toolingService.create(new sObject[] { apexExecutionOverlayAction });
SaveResult triggerSaveResult = results[0];
if (!triggerSaveResult.success)
{
Assert.Fail(triggerSaveResult.errors[0].message);
}
Assert.IsTrue(triggerSaveResult.success);
Note that this didn't make the Heap Dump Location appear in the developer console for the session owner. I logged in as the target user, but it appears I've broken the developer console for that user:
However, after hitting the dump point you can pull the resulting dump out from the ToolingService using the ApexLog. E.g.
QueryResult apexdumpLogResult = toolingService.query("Select Id, Application, DurationMilliseconds, Location, LogUserId, Operation from ApexLog where Location = 'HeapDump'");
Just so I understand, you did the following steps:
- Set the monitored portal users in the Debug Log Page
- Open the developer console and unchecked "Show my current logs only" (sort by time so new logs show up on top)
- Executed apex as the portal user
After those steps, a log should appear in the developer console or the Debug Logs page. If no log appeared with the user in the monitored users list, then you should open a case.
Let me take a minute to go over how Trace Flags are used. Trace Flags have 3 different fields we care about.
- scopeId : The scope at which we generate a "debug" or "system" log. The only difference is the way the logs are stored. Supports either a user id, empty id, or null.
- tracedEntityId : The entity we want to trace. Either a user id or an apex class/trigger.
- expirationDate : When we should we stop logging.
Monitored users (debug logs) create a trace flag with a scopeId = null and tracedEntityId = "id of user to monitor".
Developer console (system logs) create a trace flag with a scopeId = "id of you" and traceEntityId = "id of you". If you close the developer console, it will expire just that one trace flag so system logs stop being generated. This is what happens when the developer console is open for too long being "idle" is the trace flags expire, so resume will re-enable the trace flags. The log panel in the developer console only shows apex logs create by you since the console was open or 'Clear'ed. When you uncheck "Show my current logs only" it should show all the apex classes on the org, regardless of user or type.
If you set up class level filtering, it will create a trace flagwith the tracedEntityId to the class you want, and will be applied for all users (debug and system).
When I say "create" above, I really mean it will check if one already exist. If so, it will update the expiration date. If not, it will create one. That known issue specific to monitored users in the Debug Logs page is because it wasn't setting the expiration correctly. That is why deleting it works, because then it will create a new one.
Best Answer
You can create user trace flags for your users. Go to
Setup -> Monitoring -> Debug Logs -> New
Traced Entity Name is your user then create a new log level and adjust log levels as you desire. Adjust log start and expiration time and save. After this you see logs of your users in Debug Logs.