Sid Ngeth's Blog A blog about anything (but mostly development)

Integrating Prometheus for Monitoring a Rails Application

Monitoring is a crucial aspect of maintaining the reliability and performance of any application. In this post, we’ll explore how to integrate Prometheus, a free and open-source monitoring system, with a Ruby on Rails application for observability. We’ll cover tracking HTTP requests and exceptions, visualizing metrics, and setting up alerts, all using open-source tools.

What is Prometheus?

Prometheus is a powerful monitoring and alerting toolkit designed for recording real-time metrics in a time-series database. It allows you to scrape metrics from your application and provides a flexible query language, PromQL, for analyzing them.

Setting Up Prometheus with Rails

To integrate Prometheus into your Rails application, you will need to follow these steps:

1. Install the prometheus-client Gem

Add the prometheus-client gem to your Gemfile:

gem 'prometheus-client'

Then run:

bundle install

2. Configure Metrics in an Initializer

Create a new initializer (e.g., config/initializers/prometheus_metrics.rb) and set up your metrics:

require "prometheus/client"

prometheus = Prometheus::Client.registry

# Counter for HTTP requests
http_requests = prometheus.counter(:http_requests_total, docstring: "A counter of HTTP requests made.", labels: [:method, :path])

# Counter for exceptions
http_exceptions = prometheus.counter(:http_exceptions_total, docstring: "Total number of exceptions raised.")

# Expose metrics for Rails requests
ActiveSupport::Notifications.subscribe("process_action.action_controller") do |name, start, finish, id, payload|
  http_requests.increment(labels: { method: payload[:method], path: payload[:path] })
end

3. Handle Exceptions with Notifications

In your ApplicationController, use ActiveSupport Notifications to capture exceptions:

# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  # Emit a notification for unhandled exceptions
  rescue_from StandardError do |exception|
    # Notify about the exception
    ActiveSupport::Notifications.instrument("exception.action_controller", exception: exception)

    # Optionally log the exception
    Rails.logger.error(exception.message)

    # Render a generic error message
    render plain: 'Internal Server Error', status: :internal_server_error
  end
end

And subscribe to this notification in your initializer:

# Subscribe to the exception notification
ActiveSupport::Notifications.subscribe("exception.action_controller") do |name, start, finish, id, payload|
  http_exceptions.increment
end

4. Expose a Metrics Endpoint

To collect and expose your application’s metrics efficiently, you can use Prometheus middleware in your Rack configuration. This middleware automatically handles metrics collection and exposure, making it easy to get started.

# config.ru
require 'rack'
require 'prometheus/middleware/collector'
require 'prometheus/middleware/exporter'

use Rack::Deflater
use Prometheus::Middleware::Collector
use Prometheus::Middleware::Exporter

run Rails.application

With this setup, the middleware will automatically expose your Prometheus metrics at the /metrics endpoint, allowing Prometheus to scrape the data without the need for additional controller actions.

Benefits of Using Standardized Metrics

  • Automatic Collection: The middleware collects standardized metrics such as request counts, response times, and error rates without any manual coding required. This minimizes the chances of errors in metric implementation and ensures consistency across different applications.

  • Simplicity: By leveraging standardized metrics, you can avoid the overhead of managing custom metrics unless absolutely necessary, allowing you to focus on your application’s core functionality.

When to Use Custom Metrics

While standardized metrics cover many common use cases, there may be instances where custom metrics are essential to capture specific aspects of your application’s performance or business logic.

  • Tailored Insights: Custom metrics allow you to track unique user interactions or application performance indicators that standardized metrics might not address.

  • Greater Flexibility: Implementing custom metrics provides you the flexibility to adapt your monitoring strategy as your application evolves. However, keep in mind that this approach may require additional maintenance and careful planning to ensure that the metrics remain relevant and accurately reflect your application’s behavior.

In summary, using the middleware to expose a /metrics endpoint provides a quick and efficient way to leverage the power of Prometheus in your Rails application, whether through standardized metrics or tailored custom ones.

5. Start Prometheus

Make sure you have Prometheus installed and running. Use a configuration file (e.g., prometheus.yml) to define your scrape configuration:

scrape_configs:
  - job_name: 'rails_app'
    static_configs:
      - targets: ['localhost:3000']  # Adjust the port if needed

6. Access the Prometheus Web Interface

Prometheus provides a built-in web interface to view metrics. You can access it at http://localhost:9090. Use the Graph tab to query metrics using PromQL.

7. Setting Up Grafana (Optional)

While Prometheus has a web interface, many users prefer to visualize metrics using Grafana. You can find installation instructions on the Grafana website.

Start Grafana on a different port (e.g., 3001 set in the grafana.ini or defaults.ini if you run rails on 3000):

grafana server # you will have to login with default user and pass admin/admin

Add Prometheus as a data source in Grafana by navigating to Configuration > Data Sources and selecting Prometheus.

8. Alerts with Prometheus

To set up alerts, define alerting rules in your Prometheus configuration. For instance, you can create an alert for exceptions:

groups:
  - name: alerting_rules
    rules:
      - alert: HighHttpExceptions
        expr: http_exceptions_total > 10
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High number of HTTP exceptions"
          description: "More than 10 exceptions in the last 5 minutes."

Viewing Metrics Without Grafana

You can view Prometheus metrics directly without Grafana. Use the Prometheus web interface to run queries and visualize metrics as graphs. Simply navigate to http://localhost:9090 and explore the metrics.

Prometheus

comments powered by Disqus