Nouveau : Datasets open source gratuits disponibles !Decouvrir →
📊
Intermediaire 20 min Rails

Logging et monitoring Rails

Pourquoi Logging et monitoring Rails ?

Au quotidien, un développeur Ruby on Rails peut rencontrer des problèmes imprévus que le debugger ne peut pas capturer tout seul. Un bon système de logging et de monitoring est essentiel pour identifier les erreurs, comprendre leur source et les corriger rapidement.

Un cas concret : imaginez une application web qui gère des paiements pour des clients. Si un utilisateur rencontre un problème avec son paiement, comment saura-t-on que le problème vient du côté serveur ? Avec une bonne configuration de logging et de monitoring, vous pourriez détecter ce problème dans les journaux et diagnostiquer rapidement l'origine.

Prerequis

  • Connaissance avancée de Ruby on Rails
  • Familiarité avec les bases de la programmation asynchrone et des tâches en arrière-plan (Background Jobs)
  • Connaissance des outils de monitoring et logging comme Sidekiq, Delayed Job ou ActiveJob
  • Expérience avec les systèmes d'alerte et de notifications

Concepts fondamentaux

Logging

Le logging est le processus de stockage des informations sur l'exécution d'une application. Ces informations peuvent être utilisées pour déboguer les erreurs, surveiller les performances et analyser les tendances.

Schéma mental :

  • Logger : Objet qui enregistre les messages.
  • Levels : Niveaux de gravité des messages (DEBUG, INFO, WARN, ERROR, FATAL).
  • Files : Destination des journaux (console, fichiers).
## config/environments/development.rb
Rails.application.configure do
  config.logger = Logger.new(STDOUT)
  config.log_level = :debug
end

Monitoring

Le monitoring est le processus de surveillance en temps réel de la performance et des état d'une application. Cela permet de détecter les problèmes et de prendre des mesures immédiates.

Schéma mental :

  • Metrics : Mesures clés de performance (CPU, mémoire, requêtes HTTP).
  • Alerts : Notifications automatiques en cas de défaillance.
  • Dashboard : Vue d'ensemble des performances et des alertes.

Middleware

Les middleware sont des composants qui s'exécutent entre les requêtes et les réponses dans le cycle de traitement des requêtes d'une application Rails. Ils peuvent être utilisés pour ajouter des fonctionnalités comme la compression, la sécurité et le logging.

Schéma mental :

  • Request : Requête HTTP.
  • Response : Réponse HTTP.
  • Middleware Stack : Ordre des middleware à exécuter.
## app/middleware/custom_logger.rb
class CustomLogger
  def initialize(app)
    @app = app
  end

  def call(env)
    Rails.logger.info "Request received: #{env['REQUEST_URI']}"
    status, headers, body = @app.call(env)
    Rails.logger.info "Response sent: #{status}"
    [status, headers, body]
  end
end

Mise en pratique : projet fil rouge

Mini-projet : Gestionnaire de tâches

Nous allons créer un simple gestionnaire de tâches avec les fonctionnalités suivantes :

  • Ajouter une nouvelle tâche
  • Marquer une tâche comme terminée
  • Supprimer une tâche

Étape 1 : Configuration du projet

rails new task_manager
cd task_manager

Étape 2 : Création des modèles et migrations

rails generate model Task title:string description:text completed:boolean
rake db:migrate

Étape 3 : Création des contrôleurs et vues

rails generate controller Tasks index new create edit update destroy

Créer les vues correspondantes dans app/views/tasks.

Étape 4 : Implémentation des routes

Modifier config/routes.rb pour ajouter les routes nécessaires.

Rails.application.routes.draw do
  resources :tasks, only: [:index, :new, :create, :edit, :update, :destroy]
end

Étape 5 : Ajout de middleware personnalisé

Ajouter le middleware CustomLogger dans app/middleware/custom_logger.rb.

## app/middleware/custom_logger.rb
class CustomLogger
  def initialize(app)
    @app = app
  end

  def call(env)
    Rails.logger.info "Request received: #{env['REQUEST_URI']}"
    status, headers, body = @app.call(env)
    Rails.logger.info "Response sent: #{status}"
    [status, headers, body]
  end
end

Ajouter le middleware dans config/application.rb.

## config/application.rb
module TaskManager
  class Application < Rails::Application
    # Middleware custom pour logging des requêtes
    config.middleware.use CustomLogger
  end
end

Étape 6 : Ajout de monitoring avec Prometheus et Sidekiq

Installer les gems nécessaires.

gem 'prometheus-client'
gem 'sidekiq'
bundle install

Créer un fichier config/prometheus.yml pour configurer Prometheus.

## config/prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'rails'
    static_configs:
      - targets: ['localhost:3000']

  - job_name: 'sidekiq'
    static_configs:
      - targets: ['localhost:7418']

Créer un fichier config/sidekiq.yml pour configurer Sidekiq.

## config/sidekiq.yml
---
:concurrency: 25

:queues:
  - default
  - mailers

Étape 7 : Ajout de logging personnalisé

Ajouter des logs personnalisés dans le middleware et les contrôleurs.

## app/middleware/custom_logger.rb
class CustomLogger
  def initialize(app)
    @app = app
  end

  def call(env)
    Rails.logger.info "Request received: #{env['REQUEST_URI']}"
    status, headers, body = @app.call(env)
    Rails.logger.info "Response sent: #{status}"
    [status, headers, body]
  end
end
ruby
## app/controllers/tasks_controller.rb
class TasksController < ApplicationController
  def index
    Rails.logger.info 'Listing tasks'
    @tasks = Task.all
  end

  def new
    Rails.logger.info 'Creating a new task'
    @task = Task.new
  end

  def create
    Rails.logger.info 'Creating task with params: #{params[:task]}'
    @task = Task.new(task_params)
    if @task.save
      Rails.logger.info 'Task created successfully'
      redirect_to tasks_path, notice: 'Task was successfully created.'
    else
      Rails.logger.error 'Failed to create task'
      render :new
    end
  end

  def edit
    Rails.logger.info "Editing task with id #{params[:id]}"
    @task = Task.find(params[:id])
  end

  def update
    Rails.logger.info "Updating task with params: #{params[:task]} and id #{params[:id]}"
    @task = Task.find(params[:id])
    if @task.update(task_params)
      Rails.logger.info 'Task updated successfully'
      redirect_to tasks_path, notice: 'Task was successfully updated.'
    else
      Rails.logger.error 'Failed to update task'
      render :edit
    end
  end

  def destroy
    Rails.logger.info "Deleting task with id #{params[:id]}"
    @task = Task.find(params[:id])
    @task.destroy
    Rails.logger.info 'Task deleted successfully'
    redirect_to tasks_path, notice: 'Task was successfully destroyed.'
  end

  private

  def task_params
    params.require(:task).permit(:title, :description, :completed)
  end
end

Erreurs frequentes et debugging

Erreur 1 : NoMethodError dans un contrôleur

Message d'erreur :

NoMethodError (undefined method `save' for nil:NilClass):
  app/controllers/tasks_controller.rb:16:in `create'

Code incorrect :

def create
  @task = Task.new(params[:task])
  if @task.save
    redirect_to tasks_path, notice: 'Task was successfully created.'
  else
    render :new
  end
end

Code correct :

def create
  @task = Task.new(task_params)
  if @task.save
    redirect_to tasks_path, notice: 'Task was successfully created.'
  else
    render :new
  end
end

private

def task_params
  params.require(:task).permit(:title, :description, :completed)
end

Erreur 2 : ActiveRecord::RecordInvalid dans un contrôleur

Message d'erreur :

ActiveRecord::RecordInvalid (Validation failed: Title can't be blank):
  app/controllers/tasks_controller.rb:16:in `create'

Code incorrect :

def create
  @task = Task.new(params[:task])
  if @task.save!
    redirect_to tasks_path, notice: 'Task was successfully created.'
  else
    render :new
  end
end

Code correct :

def create
  @task = Task.new(task_params)
  if @task.save!
    redirect_to tasks_path, notice: 'Task was successfully created.'
  else
    render :new
  end
end

private

def task_params
  params.require(:task).permit(:title, :description, :completed)
end

Erreur 3 : Sidekiq::Worker::Error dans un worker Sidekiq

Message d'erreur :

Sidekiq::Worker::Error (undefined method `perform' for nil:NilClass):
  app/workers/my_worker.rb:5:in `perform'

Code incorrect :

class MyWorker
  include Sidekiq::Worker

  def perform(arg)
    task = Task.find(arg)
    task.perform!
  end
end

Code correct :

class MyWorker
  include Sidekiq::Worker

  def perform(task_id)
    task = Task.find(task_id)
    task.perform!
  end
end

Pour aller plus loin

Piste 1 : Utilisation de Sentry pour le monitoring des erreurs en production

Lien vers la documentation de Sentry avec Rails : https://docs.sentry.io/platforms/ruby/

Piste 2 : Intégration de New Relic pour le monitoring des performances

Lien vers la documentation de New Relic avec Rails : https://docs.newrelic.com/docs/ruby/new-relic-ruby/getting-started/install-new-relic-rails/

Piste 3 : Création d'un système de logging personnalisé pour les journaux métier

Créez un fichier config/initializers/custom_logger.rb et configurez un logger personnalisé qui enregistre des informations métier.

## config/initializers/custom_logger.rb
Rails.application.config.middleware.use CustomLogger, level: :info

Défi pratique : Ajout d'un système de notifications pour les tâches terminées

Implémentez une notification email ou SMS lorsqu'une tâche est marquée comme terminée.

Lien vers la documentation Action Mailer Rails : https://guides.rubyonrails.org/action_mailer_basics.html

Besoin d'aide sur Rails ?

Besoin d'aide sur un projet technique ? Decrivez-le pour des conseils personnalises.

Recevoir des conseils

Questions frequentes

Comment configurer un logger personnalisé en Rails?
Pour configurer un logger personnalisé en Rails, vous pouvez ajouter une configuration dans le fichier `config/environments/development.rb`. Utilisez `config.logger = Logger.new(STDOUT)` pour envoyer les logs sur la console ou utilisez `config.logger = Logger.new('path/to/file.log')` pour les sauvegarder dans un fichier.
Quels sont les avantages de l'utilisation du middleware Rack en monitoring Rails?
L'utilisation du middleware Rack en monitoring Rails vous permet d'inspecter et de mesurer le temps de réponse des requêtes HTTP, ainsi que la nature des requêtes (GET, POST, etc.). Cela aide à identifier les performances lentes ou les problèmes techniques.
Comment intégrer un service de monitoring tiers comme New Relic dans un projet Rails?
Pour intégrer New Relic dans votre projet Rails, vous devez d'abord créer un compte sur le site web de New Relic. Ensuite, installez la gem `newrelic_rpm` en exécutant `bundle add newrelic_rpm` et ajoutez votre clé d'application à votre fichier `config/newrelic.yml`. Activez les fonctionnalités souhaitées dans le portail New Relic.

Pages liees

Chaque semaine, le meilleur de la tech francaise

Tendances, salaires, outils et opportunites — directement dans votre boite mail.

Gratuit. Desabonnement en un clic. Pas de spam.