Skip to content
Rohit Macherla

Creating a Salesforce API that can be invoked by Prometheus

monitoring, salesforce2 min read

This is a part of series of blog posts about advanced monitoring techniques for your application so your business can rely on the tech team.

So far, we've covered:

  1. A case for better monitoring
  2. Slack alerts for
  3. Taking it to the next level for monitoring the Enterprise
  4. Installing Prometheus on Heroku
  5. Prometheus metrics and API structure

Building the API

I've built a small repository that exposes Governor Limits on the Org as a Salesforce API for Prometheus here. It serves as a starting point, or an example of how you could build your own APIs.

Deploy this code to your Salesforce Org and follow the steps in the README. The service will be available at <public site url>/services/apexrest/api/v1/prometheus and returns a json response. As this is an example, the service is exposed on the public site. Please use a proper authentication mechanism when you are using this. This is the documentation from Prometheus docs that'll help.

Overview of the repo

The code in the repository is straight forward. We've exposed one REST API that returns the metrics. It is designed to use a few providers - classes of type MetricsProvidable - that respond with a List of PrometheusMetrics. At the moment, this example only uses a LimitsMetricProvider which exposes Governor Limits at the Org level as metrics.

These PrometheusMetric records are then converted to a format acceptable to Prometheus, and then returned in the response.


Each metric I've used follows the pattern sfdc_limits_<limitname>_max to denote the maximum value allowed by Salesforce (the Limit) or sfdc_limits_<limitname>_current to denote the current value used by the system. A simple Grafana expression doing a subtraction will let us know how much we've got left and can easily be alerted on.

Ex.: Alert when Daily API Requests reach 70%.

Metrics that involve data storage are shown in MB according to Salesforce, and as Prometheus asks us to strip it down to the base metric - bytes in this case - these are converted to bytes and have an extra _bytes suffix to indicate as such.


To demonstrate use of labels, I've created a simple label called environment that'll let us know whether it's production or other integration environments. You can add your own labels to each of these metrics too.

Next steps

You can extend this to have your own provider classes that can, say, expose number of opportunities created or number of cases created etc. You might also want to log any errors too.


When I deployed this to my scratch org and ran the API, here's a response I got:

1sfdc_limits_dailyasyncapexexecutions_max{environment="int"} 250000
2sfdc_limits_dailyasyncapexexecutions_current{environment="int"} 0
3sfdc_limits_dailyapirequests_max{environment="int"} 5000000
4sfdc_limits_dailyapirequests_current{environment="int"} 4
5sfdc_limits_dailybulkapibatches_max{environment="int"} 15000
6sfdc_limits_dailybulkapibatches_current{environment="int"} 0
7sfdc_limits_dailygenericstreamingapievents_max{environment="int"} 10000
8sfdc_limits_dailygenericstreamingapievents_current{environment="int"} 0
9sfdc_limits_dailybulkv2queryfilestoragemb_max_bytes{environment="int"} 1023999475712
10sfdc_limits_dailybulkv2queryfilestoragemb_current_bytes{environment="int"} 0

It's coming along nicely now. Let's integrate this with Prometheus in the next chapter and we'll close off after that.