デバッグのヒント

ここでは、本番環境でイシューをデバッグする際のヒントをいくつか紹介します。

Railsコンソールセッションの開始

GitLabインスタンスのトラブルシューティングやデバッグには、Railsコンソールが必要になることがよくあります。

オムニバス・インストール用

sudo gitlab-rails console

ソースからのインストールの場合

sudo -u git -H bundle exec rails console -e production

Kubernetes: コンソールはタスクランナーポッドにあります。詳細はKubernetesチートシートを参照してください。

アクティブレコードのロギングの有効化

を実行すると、RailsのコンソールセッションでActive Recordのデバッグログの出力を有効にできます:

ActiveRecord::Base.logger = Logger.new(STDOUT)

これにより、コンソールで実行したRubyコードによってトリガーされたデータベースクエリに関する情報が表示されます。 ロギングを再びオフにするには、次のように実行します:

ActiveRecord::Base.logger = nil

データベース文のタイムアウトの無効化

を実行すると、現在のRailsコンソールセッションのPostgreSQLステートメントのタイムアウトを無効にできます:

ActiveRecord::Base.connection.execute('SET statement_timeout TO 0')

この変更は現在のRailsコンソールセッションにのみ影響し、GitLabの本番環境や次のRailsコンソールセッションでは永続化されないことに注意してください。

Railsコンソールセッション履歴の出力

Railsコンソールのコマンド履歴をコピーしやすい形式で出力し、将来の参照用に保存したい場合は、次のように実行します:

puts Readline::HISTORY.to_a

Rails Runnerの使い方

GitLabの本番環境のコンテキストでRubyコードを実行する必要がある場合は、Rails Runnerを使って実行できます。 スクリプトファイルを実行する場合は、スクリプトにgit ユーザーがアクセスできる必要があります。

オムニバス・インストール用

sudo gitlab-rails runner "RAILS_COMMAND"

# Example with a two-line Ruby script
sudo gitlab-rails runner "user = User.first; puts user.username"

# Example with a ruby script file
sudo gitlab-rails runner /path/to/script.rb

ソースからのインストールの場合

sudo -u git -H bundle exec rails runner -e production "RAILS_COMMAND"

# Example with a two-line Ruby script
sudo -u git -H bundle exec rails runner -e production "user = User.first; puts user.username"

# Example with a ruby script file
sudo -u git -H bundle exec rails runner -e production /path/to/script.rb

メール不通

よくあるトラブルが、何らかの理由でメールが送信されないというものです。 SMTPサーバーを設定したのに、メールが配信されないとします。 設定を確認する方法を説明します:

  1. Railsコンソールを実行します。

  2. ActionMailerdelivery_method を見て、意図したものと一致していることを確認してください。 SMTP を設定した場合は、:smtpと表示されるはずです。 Sendmail を使用している場合は、:sendmailと表示されるはずです:

    irb(main):001:0> ActionMailer::Base.delivery_method
    => :smtp
    
  3. SMTPを使用している場合は、メール設定を確認してください:

    irb(main):002:0> ActionMailer::Base.smtp_settings
    => {:address=>"localhost", :port=>25, :domain=>"localhost.localdomain", :user_name=>nil, :password=>nil, :authentication=>nil, :enable_starttls_auto=>true}
    

    上記の例では、SMTPサーバーはローカル・マシンに設定されています。これが意図的なものであれば、ローカルのメール・ログ(例:/var/log/mail.log)で詳細を確認する必要があるかもしれません。

  4. コンソールからテストメッセージを送信します。

    irb(main):003:0> Notify.test_email('youremail@email.com', 'Hello World', 'This is a test message').deliver_now
    

    メールが届かない、またはエラーメッセージが表示される場合は、メールサーバーの設定を確認してください。

高度なイシュー

より高度なイシューのデバッグには、gdb

GNUプロジェクトデバッガ (gdb)

Ubuntu/Debianにインストールするには:

sudo apt-get install gdb

CentOSの場合:

sudo yum install gdb

アールブトレース

GitLab 11.2にはrbtraceが同梱されており、Rubyコードのトレース、実行中の全スレッドの表示、メモリダンプの取得などが可能です。 ただし、デフォルトでは有効になっていません。有効にするには、環境変数にENABLE_RBTRACE 。 例えば、Omnibus:

gitlab_rails['env'] = {"ENABLE_RBTRACE" => "1"}

その後、システムを再設定し、UnicornとSidekiqを再起動します。 Omnibusでこれを実行するには、rootとして実行します:

/opt/gitlab/embedded/bin/ruby /opt/gitlab/embedded/bin/rbtrace

よくある問題

以下、問題を診断するためのヒントの多くは、さまざまな状況に当てはまります。 具体的な例を挙げて、何が問題なのかを知るために何ができるかを説明します。

502 Unicorn が 100% CPU でスピンした後のゲートウェイのタイムアウト

このエラーは、Unicornワーカーからの応答がないままWebサーバーがタイムアウト(デフォルト:60秒)したときに発生します。 この処理中にCPUが100%になった場合は、何か時間がかかっている可能性があります。

このイシューを解決するには、まず何が起こっているのかを知る必要があります。 以下のヒントは、ダウンタイムによるユーザーの影響を気にしない場合にのみお勧めします。 そうでない場合は、次のセクションに進んでください。

  1. 問題のあるURLをロード
  2. sudo gdb -p <PID> を実行して Unicorn プロセスにアタッチします。
  3. gdbウィンドウで次のように入力します:

    call (void) rb_backtrace()
    
  4. これはプロセスにRubyのバックトレースを生成させます。/var/log/gitlab/unicorn/unicorn_stderr.log 、バックトレースを確認してください。例えば、以下のように表示されます:

    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:33:in `block in start'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:33:in `loop'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:36:in `block (2 levels) in start'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:44:in `sample'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:68:in `sample_objects'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:68:in `each_with_object'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:68:in `each'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:69:in `block in sample_objects'
    from /opt/gitlab/embedded/service/gitlab-rails/lib/gitlab/metrics/sampler.rb:69:in `name'
    
  5. 現在のスレッドを見るには

    thread apply all bt
    
  6. gdbでのデバッグが終わったら、必ずプロセスを切り離して終了してください:

    detach
    exit
    

これらのコマンドを実行する前にUnicornプロセスが終了すると、gdbがエラーを報告することに注意してください。 より多くの時間を稼ぐには、Unicornのタイムアウトをいつでも上げることができます。 omnibusユーザーの場合は、/etc/gitlab/gitlab.rb を編集して60秒から300秒に増やすことができます:

unicorn['worker_timeout'] = 300

ソース・インストールの場合は、config/unicorn.rbを編集してください。

変更を有効にするために GitLab を再設定します。

他のユーザーに影響を与えないトラブルシューティング

前節では実行中のUnicornプロセスにアタッチしましたが、この間にGitLabにアクセスしようとするユーザーには望ましくない影響があるかもしれません。 本番システム中に他の人に影響が及ぶことを心配する場合は、別のRailsプロセスを実行してイシューをデバッグすることができます:

  1. GitLabアカウントにログインします。
  2. 問題のあるURLをコピーしてください(例:https://gitlab.com/ABC)。
  3. ユーザーの個人アクセストークンを作成します(プロフィール設定 -> アクセストークン)。
  4. GitLabRailsコンソールを表示します。
  5. Railsのコンソールで実行します:

    app.get '<URL FROM STEP 2>/?private_token=<TOKEN FROM STEP 3>'
    

    使用例:

    app.get 'https://gitlab.com/gitlab-org/gitlab-foss/-/issues/1?private_token=123456'
    
  6. 新しいウィンドウで、topを実行してください。 このRubyプロセスが100%のCPUを使用していることが表示されるはずです。 PIDを書き留めてください。
  7. gdbを使う前のセクションのステップ2に従ってください。

GitLab: APIにアクセスできません。

これは、GitLab Shellが内部API(例えば、http://localhost:8080/api/v4/internal/allowed)を使って認可を要求しようとして、チェックの中で何かが失敗したときによく起こります。 これが起こる理由はたくさんあります:

  1. データベース(PostgreSQLやRedisなど)への接続タイムアウト
  2. Gitフックまたはプッシュルールのエラー
  3. リポジトリへのアクセスエラー(NFSハンドルが古いなど)

この問題を診断するには、問題を再現してみて、top経由でスピンしている Unicorn ワーカーがあるかどうかを調べます。 上記のgdbテクニックを使ってみてください。 さらに、strace を使うと、問題の切り分けに役立つかもしれません:

strace -ttTfyyy -s 1024 -p <PID of unicorn worker> -o /tmp/unicorn.txt

どの Unicorn ワーカーがイシューか特定できない場合は、すべての Unicorn ワーカーでstraceを実行し、/internal/allowed エンドポイントがスタックしている場所を確認してください:

ps auwx | grep unicorn | awk '{ print " -p " $2}' | xargs  strace -ttTfyyy -s 1024 -o /tmp/unicorn.txt

/tmp/unicorn.txt の出力は、根本原因の診断に役立つかもしれません。

詳細情報