Client Libraries

Instrumentation in Prometheus is implemented with "client libraries". Client libraries are available in a variety of languages, including Python, Java and Go.

Client libraries are used inside your code to add instrumentation. A simple example of instrumentation would be tracking the number of HTTP requests that have been received, which would be a Counter.

Client libraries take care of all the nitty gritty details like concurrency handling and tracking state. For example if you want to track how often a function is called you do not need to maintain a thread-safe variable yourself and register a callback. Rather you would create a Counter which you call inc() when the function is entered, and the client library handles the rest. Across the thousands of metrics that you'll create over time, this saves a lot of code and clutter.

Client libraries also expose the metrics in a format Prometheus can then scrape over HTTP and understand. Exposition is separate from instrumentation. Instrumentation for a metric will register itself with the client library, and any exposition mechanism can then use that with no coordination between the two.

For example, this means if one of your dependencies has Prometheus instrumentation, but none of the rest of your code uses a client library, then that instrumentation will sit there never being exposed. You can then add exposition to your code in the form of a HTTP /metrics endpoint and instrumentation across all of your binary will automatically be included when it is scraped. Due to this it is safe to add Prometheus instrumentation, even if only some of your users use Prometheus.

Thus it is normal that exposition is handled in (very roughly speaking) your main() function, and instrumentation for each metric is self-contained and liberally spread across your code base.