Моніторинг Rails за допомогою Rails Performance Gem

Щоб моніторити час, який сервер витрачає на обробку певних запитів, можна використовувати гем Rails Performance. Цей гем дає змогу відслідковувати пропускну здатність і аналізувати запити на сервері через спеціальну панель управління.

Для початку потрібно створити Rails додаток і додати геми 'redis' і 'rails_performance' у ваш Gemfile. Далі необхідно виконати кілька простих кроків:

  1. Встановити залежності.
  2. Налаштувати додаток.
  3. Запустити сервер Redis.
  4. Запустити Rails додаток.
  5. Надіслати запити до сервера.
  6. Відкрити панель управління Rails Performance.
  7. Перевірити результати.

Першим кроком є додавання необхідних гемів до Gemfile і виконання команди bundle install. Далі репозиторій гема надає інструкції для налаштування Rails додатка. Для цього є команда, яка генерує файл конфігурації за замовчуванням, але його може знадобитися налаштувати під ваші потреби. Ось як виглядає мій конфігураційний файл config->initializers->rails_performance.rb:

if defined?(RailsPerformance)
RailsPerformance.setup do |config|
# Конфігурація Redis
config.redis = Redis.new(url: ENV["REDIS_URL"].presence || "redis://127.0.0.1:6379/0")

# Всі дані, які ми збираємо
config.duration = 4.hours

# Налаштування для останніх запитів
config.recentrequeststimewindow = 60.minutes
# confog.recent
requests_limit = nil # кількість останніх запитів

# Налаштування для повільних запитів
config.slowrequeststimewindow = 4.hours
# config.slow
requestslimit = 500 # кількість повільних запитів
config.slow
requests_threshold = 500 # мс

config.debug = false # наразі не використовується
config.enabled = true

# стандартний шлях для підключення гема
config.mount_at = "/rails/performance"

# захистіть вашу панель керування Performance за допомогою HTTP BASIC пароля
config.httpbasicauthenticationenabled = false
config.http
basicauthenticationusername = "railsperformance"
config.httpbasicauthentication_password = "password12"

# якщо вам потрібні додаткові правила для перевірки доступу користувача
config.verifyaccessproc = proc { |controller| true }
# наприклад, коли у вас є current_user
# config.verifyaccessproc = proc { |controller| controller.currentuser && controller.currentuser.admin? }

# Ви можете ігнорувати кінцеві точки за стандартною нотацією Rails controller#action
# config.ignored_endpoints = ['HomeController#contact']

# Ви можете ігнорувати шляхи запитів, вказуючи початок шляху.
# Наприклад, всі маршрути, що починаються з '/admin', можна ігнорувати:
config.ignored_paths = ["/rails/performance"]

# зберігати власні дані для запиту
# config.customdataproc = proc do |env|
# request = Rack::Request.new(env)
# {
# email: request.env['warden'].user&.email, # якщо ви використовуєте Devise
# useragent: request.env['HTTPUSER_AGENT']
# }
# end

# посилання на домашню сторінку
config.homelink = "/"
config.skipable
raketasks = ["webpacker:compile"]
config.include
raketasks = false
config.include
custom_events = true

# Якщо увімкнено, система моніторингу буде відображена на панелі керування
# щоб увімкнути, додайте необхідні геми (див. README)
# config.systemmonitorduration = 24.hours
end
end

Після налаштування ініціалізатора і встановлення гемів створіть scaffold для класу в Rails за допомогою команди ‘rails g scaffold User name:string’. Ця команда створить клас User. Виконайте ‘rails db:migrate’. Тепер потрібно змінити метод create в контролері Users.

Ось простий метод для цього:

def index
@users = User.all
render json: {users: @users}
end

def create
@user = User.new(user_params)
if @user.save
render json: {user: @user}
else
render json: {message: "user not saved"}
end
end

Якщо користувач зберігається, контролер відправить його в відповіді, в іншому випадку відобразить повідомлення про помилку. Додавши render до методу index, будуть дві кінцеві точки для моніторингу: POST /users і GET /users.

Далі можна відкрити консоль Rails, створити нових користувачів, запустити сервери Redis та Rails і перейти на localhost:3000/users. Це відправить GET запит до сервера, і панель керування Rails Performance збереже запис цієї дії.

Інший варіант — це фронтенд-додаток, який вже налаштований для відправки запитів. Якщо є форма для створення користувача, її відправка надішле POST запит до сервера, і Rails Performance також збереже запис цієї дії.

Ще один варіант — це написати тест RSpec для перевірки POST запитів. Для цього додайте ‘gem rspec’ до Gemfile і виконайте bundle install. Потім виконайте команду ‘rails g rspec:install’, щоб створити базову конфігурацію RSpec. Створіть папку spec у папці src, а також файл .rspec в головній директорії проекту, що містить ‘— require rails_helper’.

Папка spec має містити файли spec_helper.rb та rails_helper.rb, як показано нижче. Ці файли створюються автоматично після виконання команди ‘rails g rspec:install’.

rails_helper.rb

Цей файл копіюється до папки spec/ при виконанні 'rails generate rspec:install'

require 'spechelper'
ENV['RAILS
ENV'] ||= 'test'
require_relative '../config/environment'

Запобігає обрізанню бази даних, якщо середовище — production

abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'

Додає додаткові вимоги нижче цієї лінії. Rails не завантажується до цього моменту!

Вимагає підтримувані ruby файли з власними матчерами та макросами тощо, з

spec/support/ та її підкаталогів. Файли, що відповідають шаблону spec/**/*_spec.rb,

виконуються як спекли за замовчуванням. Це означає, що файли в spec/support, які закінчуються

на _spec.rb, будуть як спекли, і їх будуть виконувати двічі. Рекомендується не називати файли

за цим шаблоном з кінцевим _spec.rb. Ви можете налаштувати цей шаблон через опцію --pattern

на командному рядку або в ~/.rspec, .rspec чи .rspec-local.

Наступний рядок наданий для зручності. Однак він може уповільнити запуск, автоматично завантажуючи всі файли в каталозі support.

Ви можете вимкнути це вручну, вказуючи тільки необхідні файли підтримки в окремих *_spec.rb файлах.

Dir[Rails.root.join('spec', 'support', '*', '.rb')].sort.each { |f| require f }

Перевіряє наявність невиконаних міграцій та застосовує їх перед запуском тестів.

Якщо ви не використовуєте ActiveRecord, ці рядки можна видалити.

begin
ActiveRecord::Migration.maintaintestschema!
rescue ActiveRecord::PendingMigrationError => e
abort e.tos.strip
end
RSpec.configure do |config|
# Видаліть цей рядок, якщо ви не використовуєте ActiveRecord або фікстури ActiveRecord
config.fixture
path = "#{::Rails.root}/spec/fixtures"

# Якщо ви не використовуєте ActiveRecord, або не хочете, щоб кожен з ваших
# прикладів виконувався в транзакції, видаліть наступний рядок або встановіть false
# замість true.
config.usetransactionalfixtures = true

# Ви можете розкоментувати цей рядок, щоб повністю відключити підтримку ActiveRecord.

spec_helper.rb

Цей файл був згенерований командою rails generate rspec:install. Згідно з умовами, всі

спекли знаходяться в директорії spec, яку RSpec додає до $LOAD_PATH.

Згенерований файл .rspec містить --require spec_helper, що змусить

цей файл завантажуватись завжди, без необхідності явно імпортувати його в будь-яких

файлах.

Оскільки цей файл завантажується завжди, вам рекомендується зробити його

якомога більш легким. Вимагати важкі залежності з цього файлу

буде збільшувати час завантаження вашого тестового набору при КОЖНОМУ запуску тестів, навіть для

окремого файлу, який може не потребувати завантаження всього цього. Замість цього, подумайте про створення

окремого допоміжного файлу, який вимагатиме додаткові залежності і виконує

додаткову налаштування, і вимагайте його в спеклах, які дійсно потребують

цього.

Дивіться http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration

RSpec.configure do |config|
# налаштування rspec-expectations тут. Ви можете використовувати альтернативну
# бібліотеку асерцій/очікувань, таку як wrong або стандартні асерції/minitest,
# якщо хочете.
config.expectwith :rspec do |expectations|
# Ця опція за замовчуванням буде true в RSpec 4. Вона робить description
# і `failure
messageдля користувацьких матчерів включати текст для допоміжних методів,
# визначених за допомогою
chain`, наприклад:
# bebiggerthan(2).andsmallerthan(4).description
# # => "be bigger than 2 and smaller than 4"
# ... а не:
# # => "be bigger than 2"
expectations.includechainclausesincustommatcherdescriptions = true
end

# налаштування rspec-mocks тут. Ви можете використовувати альтернативну тестову бібліотеку
# (таку як bogus або mocha) змінивши опцію mock_with тут.
config.mockwith :rspec do |mocks|
# Запобігає вам мокати або ставити штуб на метод, який не існує на
# реальному об'єкті. Це зазвичай рекомендується, і буде встановлено на
# true в RSpec 4.
mocks.verify
partial_doubles = true
end

# Ця опція за замовчуванням буде :apply_to_host_groups в RSpec 4 (і не матиме
# способу вимкнути її — опція існує тільки для зворотної сумісності в RSpec 3). Вона дозволяє метаданим загального контексту бути
# успадкованими хешем метаданих хост-груп і прикладів, замість
# того, щоб викликати імпліцитне авто-включення в групи з відповідним метаданими.
config.sharedcontextmetadatabehavior = :applytohostgroups

Нижче наведені налаштування рекомендуються для забезпечення хорошого початкового досвіду

з RSpec, але ви можете налаштувати їх на свій смак.

=begin
# Це дозволяє обмежити запуск спеклів до окремих прикладів або груп,
# які вам важливі, позначивши їх метаданими :focus. Коли нічого
# не позначено як :focus, запускаються всі приклади. RSpec також надає
# псевдоніми для it, describe і context, які включають метадані :focus:
# fit, fdescribe і fcontext, відповідно.
config.filterrunwhen_matching :focus

# Дозволяє RSpec зберігати деякий стан між запусками для підтримки
# опцій CLI --only-failures і --next-failure.
=end

Перекладено з: Monitoring Rails with Rails Performance Gem