2023年01月26日 - Tomo Masakura    

GitLabエラートラッキングの活用

アプリケーションエラーをGitLabで視覚化するGitLabエラートラッキングの紹介とその構築方法。

どれだけお金と時間をかけてもアプリケーションのバグをゼロにはできません。本番環境でもアプリケーションエラーが発生します。このエラーはときに致命的になることもありますが、これらのエラーをすぐに捕捉・分析し、改善につなげることは重要です。これを支援するGitLabエラートラッキングを紹介します。

エラートラッキングツールの必要性

アプリケーションエラーを利用者からの報告に頼ってはいけません。報告をする利用者は少ないですし、正確で有用な報告をしてくれる利用者はまれです。結果として、開発者はエラーの原因を特定するのに時間がかかります。最悪のケースでは、頻発している重大なエラーを、報告が不十分なために、開発者が大したことがないと思いこんで優先度を下げて放置してしまうことです。

それを解決するために、アプリケーションエラーをメールやチャットに送信するコードをアプリケーションに組み込んでいる方も多いと思います。しかしこの方法では、些細な大量のエラーがチャットに流れ、ノイズとなってしまい、重要なエラーを見逃しがちです。

エラートラッキングツールはアプリケーションエラーの追跡・分析に特化しています。

エラートラッキングツールのSentryの課題(アプリケーションエラー)

  • 同じアプリケーションエラーをまとめて一つとして扱います。頻度の高い些細なエラーがノイズとなることを防げます。
  • 例外情報だけでなく、利用しているブラウザーやHTTPリクエストなど、分析に必要な様々な情報も同時に収集しています。利用者に環境を確認する手間を省けますし、特定のブラウザーだけで発生しているなどの分析がすぐにできます。
  • 各言語やフレームワーク向けのSDKが用意されており、アプリケーションに簡単に組み込むことができます。
  • アプリケーションエラーの報告の失敗や負荷上昇で、アプリケーション本体の動作にあまり影響を受けないよう設計されています。

GitLabエラートラッキング

GitLabエラートラッキングは、エラートラッキングとパフォーマンス監視のツールSentryを利用しています。

アプリケーションにはSentry SDKを組み込み、アプリケーションエラーをSentryに報告するようにします。この報告したものをイベントと呼んでいます。それに対し、同じイベント(アプリケーションエラー)をまとめたものを課題(Issue)と呼んでいます。

GitLabエラートラッキングでは、GitLabのWeb UIから、このSentryの課題を分析・管理する機能です。Sentryでは課題(Issue)と呼んでいますが、そのままではGitLabのイシューと紛らわしいためか、GitLabエラートラッキング側ではエラーと呼ばれています。

GitLabエラートラッキング

GitLabエラートラッキングには、アプリケーションエラー情報を記録するためのバックエンドが二種類あります。

一つ目はSentryバックエンドと呼ばれています。Sentry環境とGitLabを連携させ、Sentryにある課題をGitLab Web UIからでも分析・管理できます。SentryはSaaS版のsentry.ioセルホスト版Sentryのどちらでも構いません。

Sentryバックエンドの構成

sentry.ioのプランと料金はPlans and Pricingをご覧ください。無料のDeveloperプランも用意されていますが、制限も多く、有料プランが必要になるでしょう。(このブログを試す程度はDeveloperプランで十分です。) セルフホスト版Sentryは無料で制限なく利用できます。

もう一つはGitLabバックエンドと呼ばれています。GitLab内蔵のSentry互換APIを利用します。Sentry環境は不要です。この機能はオープンベータなことにご注意ください。また、Sentry互換APIは、GitLabエラートラッキング用の最小限の実装しかありません。

GitLabバックエンドの構成

GitLabバックエンドはSentry環境を用意しなくてよい分だけ手軽に使い始められます。アプリケーションエラーの確認や管理はGitLabエラートラッキングでしかできないため、Sentryの持つ豊富なアプリケーションエラーの分析機能やパフォーマンス監視機能は使えません。

GitLabバックエンドを構築する

まずは、手軽に使い始められるGitLabバックエンドから試していきましょう。

GitLabバックエンドの開発ステータスは現在オープンベータで、デフォルトで無効化されています。GitLab.comでは有効化されていますので、GitLab.comで試すことをおすすめします。

オンプレミスなどセルフマネージドのGitLabで利用する方は、GitLabの機能フラグでGitLabバックエンドを有効化してください。(機能フラグの設定はGitLabの管理者でなければできません。) GitLabのサーバーにログインして、RailsコンソールでFeature.enable(:integrated_error_tracking)を入力します。

$ sudo gitlab-rails console
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.7p221 (2022-11-24 revision 168ec2b1e5) [x86_64-linux]
 GitLab:       15.7.5-ee (677cf66582b) EE
 GitLab Shell: 14.14.0
 PostgreSQL:   13.8
------------------------------------------------------------[ booted in 46.35s ]
Loading production environment (Rails 6.1.6.1)
irb(main):001:0>  Feature.enable(:integrated_error_tracking)
WARNING: Understand the stability and security risks of enabling in-development features with feature flags.
See https://docs.gitlab.com/ee/administration/feature_flags.html#risks-when-enabling-features-still-in-development for more information.
=> true

エラートラッキングを試用するためのGitLabプロジェクトを作成してください。そのプロジェクトの左サイドメニューより、設定->監視-> Error Trackingを選択し、Enable error trackingをアクティブに、Error tracking backendGitLabを選び、変更を保存ボタンで保存します。

再びError trackingを開くと、バックエンドにエラーを送信するためのSentry DSNが表示されます。これをアプリケーションに設定しますので、この画面はそのままにしておいてください。

GitLabバックエンドの設定

これでGitLab側の設定は完了です。次に、アプリケーションにSentry SDKを組み込み、エラーをGitLabへ送信できるようにしていきます。

このブログではRuby on Railsのアプリケーションを例にしますが、他の言語や他のフレームワークにも対応しています。詳しくはSentry公式ドキュメントのPlatformsをご覧ください。

なお、GitLabバックエンドはSentryとの互換性は完全ではありません。主要なプラットフォームには対応していますが、Integrated error tracking compatibility with Sentry SDKで対応状況を確認してください。

まずはRails をはじめよう!を参考に、Railsプロジェクトを作成します。

Railsをインストールし、Railsプロジェクトを作成します。

$ gem install rails
$ rails new error-tracking
$ cd error-tracking

Railsサーバーを起動して動作確認をします。

$ ./bin/rails server

...

ブラウザーでhttp://localhost:3000/にアクセスして、Railsアプリケーションが表示されるかを確認してください。

次に、Sentry公式ドキュメントのRailsを参考にSentry SDKを組み込みます。

必要なsentry-rubysentry-railsをプロジェクトに含めるために、Gemfileに次の二行を追加します。(ファイルの末尾に追記するのが確実です)

gem "sentry-ruby"
gem "sentry-rails"

次のコマンドを実行し、これらのライブラリをインストールします。

$ bundle install

Sentryの初期設定のために、config/initializers/sentry.rbファイルを作成し、次の内容を入力します。config.dsnの値は、GitLabのプロジェクトのError Trackingの設定で表示されているものをコピペしてください。

Sentry.init do |config|
  config.dsn = 'https://glet_*********@gitlab.example.com/api/v4/error_tracking/collector/3'
  config.breadcrumbs_logger = [:active_support_logger, :http_logger]

  config.traces_sample_rate = 1.0
end

設定の変更が完了したら、RailsアプリケーションをCtrl+Cで停止させ、./bin/rails serverコマンドでRailsアプリケーションを再起動してください。

以上でRailsアプリケーションへのSentryの組み込みは完了しました。これで発生したアプリケーションエラーがSentryに報告されるようになります。

GitLabエラートラッキングを試すために、ホームページを表示したらアプリケーションエラーが発生するようにします。

ホームページ用のRailsコントローラーを作成します。

$ ./bin/rails generate controller home index

ホームページでこのRailsコントローラーが表示されるようルーティング設定を変更します。

Rails.application.routes.draw do
  get 'home/index'
  root :to => 'home#index' # この行を追加します。
  # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html

  # Defines the root path route ("/")
  # root "articles#index"
end

ブラウザーをリロードすると、home#indexと表示が変わります。

ホームページの表示でエラーになるよう、作成したRailsコントローラーapp/controllers/home_controller.rbファイルを修正します。

class HomeController < ApplicationController
  def index
    raise StandardError.new("失敗!")
  end
end

ブラウザーをリロードすると、エラー画面に変わります。

Railsエラー画面

GitLabのプロジェクトで、左サイドメニューから監視->エラートラッキングを選びます。発生したアプリケーションエラーの一覧が表示されます。イベントの数がエラーの数になります。

GitLabエラートラッキングでのエラーの一覧

エラーをクリックすると、詳細を表示することができます。スタックトレースも表示されますので、原因の調査が捗るでしょう。

GitLabエラートラッキングでのエラーの詳細

GitLabエラートラッキングWeb UIでできること

GitLabエラートラッキングのWeb UIのエラーから、GitLabのイシューを作成することができます。連携されたGitLabイシューとGitLabエラーは相互に行き来ができます。

GitLabエラーと関連付けられたイシュー

エラーの状態にはUnresolved(未解決)無視済み解決済みがあります。アプリケーションエラーが報告された直後はUnresolvedとなります。

エラーを無視にすると、Unresolved(未解決)なリストから外されます。以後同じアプリケーションエラーが報告されても、Unresolvedになることはありません。

それに対して、エラーの解決はUnresolvedなリストから外されるのは同じですが、同じアプリケーションエラーが新しく報告されたらUnresolvedに戻る点が異なります。また、関連するGitLabイシューはクローズされます。

なお、GitLabバックエンドでは、解決済みで同じアプリケーションエラーが新しく報告されても、Unresolvedに戻らないようです。

Sentryバックエンドの構築

続いてSentryバックエンドの構築方法の紹介です。GitLabのプロジェクトやRailsアプリケーションはそのまま流用します。

sentry.ioもしくは別途構築しているセルフホスト版Sentryにアクセスし、ウィーザードに従ってプロジェクトを作成します。作成したプロジェクトの設定でDSNが表示されます。(詳細な手順は割愛します)

Sentryプロジェクトのセットアップ画面

表示されているDSNをconfig/initializers/sentry.rbに再設定し、Railsアプリケーションを再起動してください。

GitLabバックエンドのときと同じように、Railsアプリケーションのホームページを表示し、アプリケーションエラーを発生させてください。SentryのWeb UIで課題(Issue)を選ぶと、発生したアプリケーションエラーを見ることができます。

Sentryの課題一覧

課題をクリックすると、その課題と最後に発生したイベントの詳細を見ることができます。

Sentryの課題詳細

ここまではGitLab関係なしにSentryを使う方法です。

続けてGitLabエラートラッキングからSentryプロジェクトの課題が分析・管理ができるよう設定します。

次のスクリーンショットにあるように、Sentryの左上の組織をクリックし、APIキーを開き、新しいトークンの作成でトークンを作成します。GitLabの公式ドキュメントにあるとおり、スコープの event:read project:read event:write だけにチェックを入れて、新規作成ボタンをクリックします。

Sentry APIトークンの発行

APIトークンが発行されます。このAPIトークンをGitLabエラートラッキングに設定しますので、この画面は開いたままにしておいてください。

発行されたSentry APIトークン

GitLabプロジェクトの左サイドメニューより、設定->監視->Error trackingを開きます。

項目 設定値
Enable error tracking / アクティブ チェックを入れてください。
Error tracking backend Sentryを選んでください。
Sentry API URL SentryのホームページのURLを設定します。sentry.ioの場合は、https://sentry.ioとなります。
認証トークン 先程発行したSentryのAPIトークンを設定します。

これらの入力の完了したあと、接続ボタンをクリックします。次のスクリーンショットのように、Sentryのプロジェクトを選択できるようになりますので、連携するSentryプロジェクトを選択し、変更を保存ボタンをクリックしてください。

GitLabのSentryバックエンドの設定

GitLabプロジェクトの左サイドメニューから、監視->エラートラッキングを開くと、Sentryプロジェクトの課題と同じものを見ることができます。

GitLabエラートラッキングでSentry課題を見る

エラー(Sentry課題)の解決や無視の状態も同期されています。解決や無視をどちらから行っても問題ありません。しかし、Sentryから課題の解決を行っても、関連付けられたGitLabイシューは閉じられません。

このSentryバックエンドでは、解決したSentry課題と同じアプリケーションエラーが再度発生すると、Unresolved(未解決)に戻ります。

どちらを使うべきか

GitLabバックエンドではアプリケーションのエラーの分析や管理にGitLabエラートラッキングしか使えません。これは、Sentryの持つ強力な分析・管理機能が使えないことになります。

  • Sentry SDKはアプリケーションエラーの報告のときに、ブラウザーの種類を始めとする様々なタグ情報やHTTPリクエスト情報やモジュール情報も同時に送信します。GitLabエラートラッキングはこれにアクセスすることができません。次のような分析ではSentryが必要です。
    • 動作サポート対象でない古いブラウザーでしかエラーが発生していないから対処しなくていい
    • HTTPリクエストの特定のヘッダーが怪しい
    • Active Recordのバージョンアップが怪しい
  • Sentryは強力なエラー通知機能を持っています。メールやチャットで通知できるのももちろんですが、しきい値を利用した通知も可能です。GitLabバックエンドには通知機能はありません。
  • Sentry.capture_message(...)とアプリケーションコードに記述することで、メッセージイベントをSentryに送信できます。GitLabバックエンドではこれに対応していないようです。
  • Sentryにはパフォーマンス監視機能もありますが、GitLabバックエンドではこのSentryの機能は使えません。
  • GitLabバックエンドはパフォーマンスの問題を抱えているようです。短時間で大量のイベントを投げると、GitLab自身が重たくなるようです。

GitLabエラートラッキングは、GitLabからでもSentryの課題を確認ができてちょっと便利になる程度と考え、Sentryを中心に使うことをおすすめします。

Sentry環境の用意に時間がかかる場合や、そもそも用意できない場合はGitLabバックエンドで始めるのはいい選択です。GitLabバックエンドとSentryバックエンドでの切り替えのアプリケーション側の修正はとても簡単です。Sentry環境が用意できたら乗り換えればいいのです。

実践的に

ここまでは、GitLabエラートラッキングを試すことを優先しましたが、実際の開発プロジェクトでは最低限やっておいたほうがいいこともあります。それをいくつか紹介します。

開発者のパソコンからエラー情報が報告されても、分析のノイズになるだけで何一ついいことはありません。これを避けるために、Sentry SDKのDSNの設定はアプリケーションの設定ファイルではなく、環境変数経由で設定してください。多くのSentry SDKは環境変数SENTRY_DSNからDSNを読み取ることができます。

タグreleasepackage_name@1.2.3のようなパッケージ名とセマンティックバージョンの組か、コミットハッシュを設定することが推奨されています。なお、GitLabエラートラッキングではreleaseにコミットハッシュであることを期待します。

マージリクエストのReview Appsのエラートラッキングを行う場合は、environmentにReview Appsの環境名を埋め込んでください。

Sentry.init do |config|
  # 環境変数`GITLAB_REVIEW_APPS_ENVIRONMENT`が設定されていればそれを、
  # 未設定ならSentryのデフォルトに任せます。
  # (Sentryはデフォルトで、Railsの環境名を埋め込みます)
  if ENV['GITLAB_REVIEW_APPS_ENVIRONMENT'] then
    config.environment = ENV['GITLAB_REVIEW_APPS_ENVIRONMENT']
  end
end

フロントエンドアプリケーションとバックエンドアプリケーションの両方をエラートラッキングする場合、Sentryではそれぞれを別々のSentryプロジェクトにすることが推奨されています。ただし、GitLabエラートラッキングでは一つのSentryプロジェクトとしか連携できませんので、その場合はGitLabエラートラッキングの利用はあきらめ、Sentryのみで運用してください。なお、GitLabバックエンドはの場合は、フロントエンドアプリケーションとバックエンドアプリケーションを一つのGitLabプロジェクトで管理しているなら、そのプロジェクトにまとめてイベントを報告するようにしてください。

Sentryバックエンドを利用する場合のSentry APIトークンは、開発メンバーが発行したものではなく、ボットユーザーを作成し、そのユーザーで発行したAPIトークンを利用してください。その開発メンバーは異動するかもしれませんし、その開発メンバーがアクセスできる他のSentryプロジェクトに不正に悪用される恐れもあります。対象となるSentryの組織ごとに、その組織にしか参加していないボットユーザーを作成し、そのボットユーザーでSentry APIトークンを発行します。

SentryのGitLab連携

ここまではGitLabのSentryとの連携機能について紹介しました。ここでは、SentryのGitLabとの連携機能を簡単に紹介します。

GitLab OAuth連携

SentryはOAuth認証に対応しています。標準ではGitLabは対応していませんが、セルフホスト版Sentryでは、有志が開発したentry-auth-gitlabを利用できます。

sentry.ioは残念ながら対応してません。

GitLab連携

SentryにはGitLab連携が用意されています。

  • GitLabのコミットとリリースの追跡(すべてのプラン)
  • GitLabのコミットやマージリクエストから、Sentry課題を解決する(すべてのプラン)
  • GitLabのイシューの作成やリンク(Teamプラン以上)
  • GitLabのCode Ownersとの連携 (Businessプラン以上)

sentry.ioでは記載されているプランが必要ですが、セルフホスト版Sentryでは無料でこれらの機能を使うことができます。

GitLabエラートラッキングの将来

GitLabエラートラッキングを含むGitLab監視機能は、それ専用の監視ツールやオブザーバビリティツールとと比べると機能の不足が否めません。この状態を解消するために、GitLab社はアプリケーションログやパフォーマンスなどの統合オブザーバビリティツールであるOpstraceを買収し、これを元にGitLab Observabilityを開発しています。

GitLab監視は大きく変わる予定です。方向性はProduct Direction - Monitor:Observabilityに詳しく書かれています。どのように変わる予定なのかを簡単に紹介します。なお、あくまで予定で、計画は変更されるかもしれません。

エラートラッキング・パフォーマンスカウンター・ログなどの情報はGitLab Observability Backendが一括して保持するようになります。可視化ツールであるGrafanaを元にして開発しているGitLab Observability UIを利用して、専用のツールと同様の分析ができるようになります。

このGitLab Observability UIはGitLabと統合され、シームレスに扱えます。

GitLabに組み込まれたGitLab Observable UI (画面は開発中のもので、製品では大きく変わるそうです)

アプリケーションエラーの報告に利用している、GitLabバックエンドのSentry互換APIはそのまま残るようです。アプリケーションの修正は不要だと思われます。GitLabバックエンドでは、現在GitLabインスタンスのデータベースにイベントを記録していますが、将来はGitLab Observability Backendに記録するように変わります。

GitLab Observability UIでは、GitLab Observability Backendにあるエラートラッキング情報を分析できるのはもちろんですが、Sentryデータソースを追加し、別途構築しているSentryの課題も分析できるようになります。

これに伴い、GitLabエラートラッキングのWeb UIは廃止される予定です。

GitLabバックエンドを利用していてもSentryバックエンドを利用していても、アプリケーションの修正は不要で、より高度な分析ができるGitLab Observability UIが使えることになります。

最後に

アプリケーションエラーをいち早く捕捉し、分析し、アプリケーションのバグの解消に役立てるために、SentryGitLabエラートラッキングを活用しましょう。

エラートラキングの機能を持つSentryをフル活用するために、Sentry SaaSサービスのsentry.ioもしくはセルフホスト版Sentry環境を用意し、SentryバックエンドSentryのGitLab連携でGitLabと連携します。

Sentry環境が用意できない、もしくは用意に時間がかかる場合は、Sentryなしで利用できるGitLabバックエンドで始めましょう。

GitLabエラートラッキングは将来、より高度で専用のオブザーバビリティツールに負けない機能を持つGitLab Observabilityに置き換えられる予定です。置き換えられたとしてもアプリケーション側の修正は不要になるようです。積極的に使っていきましょう。

Gitlab x icon svg