Skip to content

Instantly share code, notes, and snippets.

@brianmfear
Last active November 30, 2023 19:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save brianmfear/d193db3dd7ff369f0dae9118938737d1 to your computer and use it in GitHub Desktop.
Save brianmfear/d193db3dd7ff369f0dae9118938737d1 to your computer and use it in GitHub Desktop.
Notify Admin when approaching Async Apex usage limit

Use this simple job to send hourly notifications to an admin if the org's limit usage for daily async executions exceeds 90%. You can use this execute anonymous script to do so.

System.schedule('MonitorAsyncUsage', '0 0 * * * ?', new MonitorAsyncUsage());
public class MonitorAsyncUsage implements Schedulable {
public class ResourceInfo {
public Integer Max;
public Integer Remaining;
}
public class LimitsAPI {
public ResourceInfo DailyAsyncApexExecutions;
}
public static LimitsAPI parse(String json) {
return (LimitsAPI) System.JSON.deserialize(json, LimitsAPI.class);
}
public void execute(SchedulableContext context) {
System.enqueueJob(new Queued());
}
public class Queued implements Queueable, Database.AllowsCallouts {
public void execute(QueueableContext context) {
HttpRequest request = new HttpRequest();
request.setHeader('Authorization', 'Bearer '+UserInfo.getSessionId());
request.setEndpoint(Url.getOrgDomainURL().toExternalForm()+'/services/data/v58.0/limits');
request.setMethod('GET');
HttpResponse response = new Http().send(request);
LimitsAPI limitsUsage = parse(response.getBody());
if(limitsUsage.DailyAsyncApexExecutions.Remaining / limitsUsage.DailyAsyncApexExecutions.Max < 0.1) {
Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
message.setTargetObjectId(UserInfo.getUserId());
message.setSubject('Approaching Apex Async Limits for org '+UserInfo.getOrganizationId());
message.setPlainTextBody(
'Current Usage: ' + limitsUsage.DailyAsyncApexExecutions.Remaining+'\n' +
'Remaining: ' + (limitsUsage.DailyAsyncApexExecutions.Max - limitsUsage.DailyAsyncApexExecutions.Remaining)
);
message.setSaveAsActivity(false);
Messaging.sendEmail(new Messaging.Email[] { message });
}
}
}
}
@isTest class MonitorAsyncUsageTest {
class ResponseMock implements HttpCalloutMock {
public HttpResponse respond(HttpRequest request) {
HttpResponse response = new HttpResponse();
MonitorAsyncUsage.LimitsAPI limitsUsage = new MonitorAsyncUsage.LimitsAPI();
limitsUsage.DailyAsyncApexExecutions = new MonitorAsyncUsage.ResourceInfo();
limitsUsage.DailyAsyncApexExecutions.Max = 1000;
limitsUsage.DailyAsyncApexExecutions.Remaining = 99;
response.setBody(JSON.serialize(limitsUsage));
return response;
}
}
@isTest static void test() {
Test.startTest();
Test.setMock(HttpCalloutMock.class, new ResponseMock());
System.schedule('JobForUnitTestMonitor', '0 0 * * * ?', new MonitorAsyncUsage());
Test.stopTest();
Assert.isTrue(true, 'Nothing to assert here; if the test passes, coverage is 100% and everything works.');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment