Как пережить DEPRECATION WARNING без психологической травмы
Всем привет! Сегодня я расскажу о нескольких способах поиска deprecation warnings при обновлении версии rails на старом проекте.
Небольшая вводная
Всякий из нас хотя бы раз сталкивался с ситуацией, когда проект использует устаревшую версию Ruby on Rails. Например, у вас может быть установлен Rails 5, в то время как большинство уже перешло на Rails 6 или 7. И рано или поздно вам придется столкнуться с задачей обновления версии Rails, что неизбежно приведет к появлению предупреждений о устаревании функций (deprecation warnings).
В этой статье описаны три подхода к легкому (или почти легкому) поиску всех deprecation warnings:
Способ "Базовый"
Если на каком-то из стендов в конфигах (config/environments/production.rb) у вас установлено config.active_support.deprecation = :log, то вам подойдет этот способ.
# Скачиваем лог с сервера по ssh rsync -apr user@host:port:/rails-app/log/production.log ~/downloads
Шаг 2: Обработка лога и поиск предупреждений об устаревании
cd ~/downloads # Ищем строки с предупреждениями о устаревании, очищаем их от лишнего текста, # Сортируем и убираем дубликаты, записываем результат в файл grep 'DEPRECATION WARNING' production.log | sed 's|.*WARNING||' | sort -u > file.txt
Шаг 3: Ручное исправление устаревших методов в проекте
Используем результаты из файла file.txt для поиска методов в проекте. Исправляем найденные методы, заменяя их на новые версии.
Если методы не найдены в проекте, но есть в логах, то, вероятно, они используются в гемах. В этом случае нужно проверить зависимости проекта и обновить гемы, которые используют устаревшие методы.
Шаг 4: Использование grep для поиска устаревших методов в гемах
# Ищем, например, метод alias_method_chain в директории с гемами grep -r alias_method_chain ~/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.1/gems/
Grep будет выводить результаты поиска, включая имя файла и саму строку, содержащую метод. Это поможет вам определить, в каком геме и файле находится этот метод.
Стоит отметить, что если у вас централизованный сбор логов (Graylog/ELK), то первые 2 шага будут отличаться. Вместо этого можно использовать функцию поиска, предоставляемую интерфейсом Graylog/ELK.
Недостатки этого подхода
1. Ограниченная активность на стенде.
Возможно, не все функции используются на стенде, что может привести к тому, что не все устаревшие методы будут отражены в логах.
2. Недостаточная история логов.
Если логи были включены недавно, то они могут не содержать всей информации об устаревших методах, что может привести к пропуску некоторых проблем.
Способ "Расширенный"
Установить config.active_support.deprecation = :notify и с помощью ActiveSupport::Notifications можно создать кастомный отлов предупреждений об устранении метода и отправлять в систему отслеживания ошибок.
Ниже пример с отправкой в чат телеграмма.
ActiveSupport::Notifications.subscribe('deprecation.rails') do |_name, _start, _finish, _id, payload| message = "Предупреждение об устаревании: #{payload[:message]}" Faraday.post "https://api.telegram.org/bot#{TG_TOKEN}/sendMessage", { chat_id: CHAT_ID, text: message } rescue StandardError => e Rails.logger.error "Проблема с отправкой предупреждения: #{e.message}" end
Недостатки этого подхода
1. Ограниченная активность на стенде
В целом, точно такая же проблема, как и в прошлом варианте.
2. Кривой код может положить стенд
В случае ошибки (не пойманного исключения) стенд может быть полностью парализован. Следует принять меры для явного подавления ошибок.
3. Большая активность на стенде
При высокой активности на стенде и большом кол-ве устаревших методов можно заспамить себя уведомлениями 🙂 (Sentry устраняет эту проблему).
Способ "Мечтательный"
Этот способ позволяет эффективно бороться с предупреждениями об устаревании. Правда, необходимо иметь хорошее покрытие тестами, желательно 100%.
Если так и есть, то рад за вас, но не от всего сердца 🙂 Если меньше, то остается только мечтать.
В файле config/environments/test.rb добавить строку config.active_support.deprecation = :raise
После этого запустить тесты и исправить все упавшие.
Заключение
Кроме того, есть полезный инструмент https://github.com/shopify/deprecation_toolkit, который может помочь в борьбе с устаревшими методами. Однако, мой основной совет - регулярно обновляйте свои зависимости и не допускайте, чтобы ваш кодовая база стала неудобоваримой. Делайте обновление Rails регулярной задачей, и ваша жизнь станет намного проще.