I need a way to programmatically identify Salesforce Governor limits and get an alert when the limits are hit.
You can use the
Limits class to determine a given limit and how close you are to reaching that limit, but you still will need some time, dml, emails, to handle hitting the limit, meaning you need to stop at say, 90% if your limits, making the rest of the code have to do 100% of the work in 90% of the time.
Plus, there are certain limits you cant access or handle, and if you miss adding a limit handler to a method, and it hits the limit, you have no notice and crashed code. You'll have to cover all your code in calls to check your limits (consuming more of your limits), increasing your dev time, and requiring extra work for testing.
You could do this, but I really don't think you should. Instead of warping your codebase to handle hitting limits, modify the code thats hitting limits to stop hitting the limit.
This is a very broad subject, but it's important to start with a distinction. Some limits are transaction-based, while others are based on a rolling 24-hour window or other threshold outside the limits of a transaction.
For example, the CPU time limit and SOQL row limit are transaction limits: they apply specifically and exclusively within the boundaries of a single transaction, and cannot be observed from outside the transaction. The Limits class includes methods like
getLimitCPUTime() that allow you to inspect (from within a transaction) your progress towards limits. Your code can use this information to make decisions like firing a new chained Queueable to continue long-running processing before you hit the limit.
However, once the transaction limit itself is hit, you cannot run any further code in that transaction that would consume the affected limit, including code that would fire an alert. That information may be surfaced through the UI (if, for example, a trigger times out on a record save) or through the Apex Jobs interface in Setup, but you can't build functionality in to do alerting there (unless you were to write scheduled code to monitor
AsyncApexJob objects, which I think would not be useful - by the time you get a lot of limits-related failures, your monitoring code is likely to fail too).
Extra-transaction limits, like the Async Apex Executions limits, often operate on a rolling 24 hour window. To take that limit as an example, you can execute a certain number (call it N) of asynchronous Apex operations across the last 24 hours. It's not a calendar day, so at 2pm today it means that your limits consumption is calculated from 2pm yesterday to right now.
While you can also observe some of these limits within a transaction, these extra-transaction limits can effectively be sampled by running a scheduled Apex job that inspects the limits using either the
Limits class or by calling out to the REST API. That job can then save samples to a custom object, against which you can run reports or dashboards, write workflow rules or triggers, and so on, or your scheduled job can directly perform alerting, like sending an email. I've built such a monitoring solution in the past and found that it works pretty well.
It's still important to note though that once the limit is hit, it applies to all code, including your monitoring code. If you hit your Async Apex limit, your monitoring code probably will not go off, so you always want to build an alerting threshold that's low enough that your code will have time to warn you before the limit is hit.