Errbitのインストールと設定

## はじめに
Railsアプリケーションのアプリケーションエラー収集のためにErrbitサーバの構築、およびRailsアプリケーションへの設定を行いました。導入した時の設定メモなどここに書こうと思います。

## Errbitって何？
アプリケーションのエラーを収集するためのツールです。通常の監視ツールでは、Pingなどを使ってサーバの死活監視やSNMPを使用してサーバの状態監視などを行いますが、Errbitはそれらとは異なります。

Errbitが収集する情報は、Webアプリケーション上で発生する例外処理などのエラーです。
例外処理を収集することによって、運用上発生する問題点を把握し、バグ修正やリファクタリングを効率的に行うことができます。

Webアプリケーションは基本Ruby(Rails)ですが、PHPやPythonでもイケるみたいです。

- https://github.com/errbit/errbit#use-errbit-with-applications-written-in-other-languages

Github Errbit

- https://github.com/errbit/errbit


Webアプリケーション側にはAirbrake(`airbrake-ruby`)を使用します。
Airbrakeは、Errbitと同じエラー収集システムでAPIの互換性があり、Airbrakeで使用するGem `airbrake-ruby`を利用してErrbitへ通知を行います。

- https://github.com/airbrake/airbrake-ruby

## 環境

AmazonのEC2上のAmazon Linux内に構築しました。

### Erribtサーバ

- MongoDB version v3.2.16
- Ruby 2.4.1
- Nginx 1.10.3
- Errbit 0.7.0-dev

### Webアプリケーションサーバ

- Ruby 2.4.1
- Rails 5.1.1
- Airbrake 6.2.1

## 注意点

Errbitで使用するGem AirbrakeですがVersion 5からインターフェースが大きく変更されています。新たにErrbitを導入する場合は問題ありませんが、ErrbitサーバとAirbrakeのGemのバージョンは注意したほうがいいです。

- https://github.com/airbrake/airbrake/blob/master/docs/Migration_guide_from_v4_to_v5.md


## Errbitの導入

### MongoDBインストール

#### 参考

- [Install MongoDB Community Edition on Amazon Linux — MongoDB Manual 3.4](https://docs.mongodb.com/manual/tutorial/install-mongodb-on-amazon/)
- [Amazon EC2 — MongoDB Ecosystem](https://docs.mongodb.com/ecosystem/platforms/amazon-ec2/)


```
# リポジトリ情報追加
$ echo "[mongodb-org-3.2]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/amazon/2013.03/mongodb-org/3.2/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.2.asc" |
  sudo tee -a /etc/yum.repos.d/mongodb-org-3.2.repo
 
# インストール
$　sudo yum -y update && sudo yum install -y mongodb-org-server \
    mongodb-org-shell mongodb-org-tools
 
# バージョン確認
$ $ mongod -version
db version v3.2.16
git version: 056bf45128114e44c5358c7a8776fb582363e094
OpenSSL version: OpenSSL 1.0.0-fips 29 Mar 2010
allocator: tcmalloc
modules: none
build environment:
    distmod: amazon
    distarch: x86_64
    target_arch: x86_64

# EBSボリュームは使用しないので、ボリュームマウント関連はスキップ
# /etc/mongo.confなどもデフォルト値を使用
 
# リソース使用に関する設定(ulimit)を変更
$ echo '* soft nofile 64000
* hard nofile 64000
* soft nproc 64000
* hard nproc 64000' | sudo tee /etc/security/limits.d/90-mongodb.conf
 
# MongoDBの起動
$ sudo service mongod start
$ sudo chkconfig mongod on
 
# Mongo shellのテスト
$ mongo
MongoDB shell version: 3.2.16
connecting to: test
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user
> exit
```

### Ruby及び関連パッケージ群の導入

#### 参考
- [Amazon LinuxにRubyの実行環境を構築してみる ｜ Developers.IO](http://dev.classmethod.jp/etc/amazon-linux_rbenv/)

```
# 必要パッケージのインストール
$ sudo yum -y install git gcc gcc-c++ openssl-devel readline-devel zlib-devel
  
# rbenvをダウンロード
$ git clone git://github.com/sstephenson/rbenv.git .rbenv
 
 
# 環境変数などの設定
$ PATH="$HOME/.rbenv/bin:$PATH"
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
 
 
# ruby-buildをダウンロード
$ git clone git://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
 
 
# rubyインストール
$ rbenv install 2.4.1
$ rbenv local 2.4.1
$ rbenv rehash
 
 
# bundlerインストール
$ gem install bundler
$ bundle -v
 
 
# git設定
$ git init
$ git config --local user.name '[githubに登録したユーザ名]'
$ git config --local user.email '[githubに登録したメールアドレス]'
```

### Errbitインストール

```
# githubからリポジトリをクローン
$ cd /var/rails
$ git clone https://github.com/errbit/errbit.git
 
$ cd errbit
 
# 必要なGemをインストール
$ bundle install --path vendor/bundle
 
 
$ bundle exec rake errbit:bootstrap
省略
-------------------------------
Creating an initial admin user:
-- email:    errbit@errbit.example.com
-- password: xxxxxxx
Be sure to note down these credentials now!
 
 
# pumaを動かしErrbit起動
$ bundle exec puma -C config/puma.default.rb
``` 

ここで表示される、email/passwordはメモしておきます。
この時点で、ErrbitのWebUIは見れるようになっているはずです。
ただ、今回はNginxをインストールして、Nginx経由でPumaにアクセスするようにします。


### Errbitに関するそのほかの設定

```
# Errbitの設定
$ vi .env
ERRBIT_HOST=[Errbitサーバのホスト名]
ERRBIT_EMAIL_FROM='[Fromに設定するメールアドレス]'
ERRBIT_PROBLEM_DESTROY_AFTER_DAYS=180
EMAIL_DELIVERY_METHOD=:smtp
SMTP_SERVER='[SNMPサーバのアドレス]'
SMTP_PORT=25
 
# pumaの設定
$ cp config/puma.default.rb config/puma.rb
$ vi config/puma.rb
 
#コメントアウト
#port ENV['PORT'] || 8080
中略
 
# 追加
app_dir = File.expand_path("../..", __FILE__)
daemonize true
 
# pid/stateファイルの格納場所を指定
pidfile "#{app_dir}/tmp/pids/puma.pid"
state_path "#{app_dir}/tmp/pids/puma.state"
 
# 設定のテスト、デーモン化での起動、再起動、停止
$ bundle exec pumactl start
$ bundle exec pumactl halt
$ bundle exec pumactl restart
$ vi config/puma.rb
 
# nginx経由でsocket接続するため、sockファイル場所を指定
bind "unix://#{app_dir}/tmp/sockets/puma.sock"
```


### Nginxインストールと設定

```
# インストールとバージョン確認
$ sudo yum -y install nginx
 
$ nginx -v
nginx version: nginx/1.10.3
 
$ sudo vi /etc/nginx/conf.d/puma.conf
server {
    #root         /usr/share/nginx/html;
    root         /var/rails/errbit/public;
    location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_set_header X-Forwarded_Proto $scheme;
            proxy_redirect off;
            proxy_pass http://unix:/var/rails/errbit/tmp/sockets/puma.sock;
    }
}
 
$ sudo service nginx restart
$ sudo chkconfig nginx on
```

Nginxの起動後、ErrbitのURLにアクセスしてAppの設定をします。

- Appタブをクリックし、画面上部にある「add a new app」ボタンを押す
- 入力フォームが表示されるので必要な項目を入力
- その後、Webアプリケーション導入時に必要な設定が表示される

表示される設定をメモします。このメモした設定を元にAirbrake側の設定を進めていきます。

### Gem Airbrakeの設定

Errbitサーバが用意できたら、対象のWebアプリケーションにAirbrakeをインストールします。
Errbitサーバからログアウトして、Webアプリケーション(Rails)に対して下記の設定を適応します。

```
#  Airbrakeのインストール
$ vi Gemfile

gem 'airbrake-ruby', '~> 2.6'

$ bundle install --path vendor/bundle

# Airbrakeの設定
$ vi config/initializers/errbit.rb

# Require the airbrake gem in your App.
# ---------------------------------------------
#
# Ruby - In your Gemfile
# gem 'airbrake', '~> 5.0'
#
# Then add the following to config/initializers/errbit.rb
# -------------------------------------------------------
Airbrake.configure do |config|
  config.host = [ErrbitサーバのURL]
  config.project_id = 1 # required, but any positive integer works
  config.project_key = [Errbitで取得したKeyを利用]
 
  # Uncomment for Rails apps
  config.environment = Rails.env
  config.ignore_environments = %w(development test)
end
```

`config.environment`はErrbit上に表示する環境名となります。
Rails.envで適切に記載していれば`staging`、 `production`などを自動で判別してくれます。

設定完了後、下記のコマンドを使用してテストを行います。

```
bundle exec rake airbrake:test
```
このコマンドにより、Errbitへテストエラーが通知されるはずです。
WebUIにアクセスして確認します。

## 通知するエラー内容のフィルタリング

```
$ vi config/initializers/errbit.rb

# 下記を追記
# The library supports nested exceptions, so one notice can carry several
# exceptions.
# Accesses a notice's payload, which can be read or filtered. Payload includes:
# - :errors
# - :context
# - :environment
# - :session
# - :params
# https://github.com/airbrake/airbrake-ruby#airbrakeadd_filter

Airbrake.add_filter do |notice|
   # モデルSampleClassのRecordNotFoundを通知から除外
   notice.ignore! if notice[:errors].any? do |error|
     error[:type] == 'ActiveRecord::RecordNotFound'
     error[:message] =~ /Couldn't find SampleClass with/
   end
end
```

Errbitでは通知しない例外を追加することができます。上記の設定では

- Airbrakeから送られるエラータイプが`ActiveRecord::RecordNotFound`
- エラー内容に `Couldn't find SampleClass with`が含まれている

上記の条件に当てはまる場合、通知を無視します。
設定ファイルといってもrubyのDSLなのでrubyを書くのと同じように条件を記載できます。

運用中に不要な通知を発見した場合は、エラーを追加していきましょう。
noticeの内容はErrbitのWebUIで表示されるエラー通知の項目とほぼ同様です。
実際に中身を確認したい場合は、Pry/Pry-byebugを使用してnoticeの中身を確認しましょう。

Pry-byebug

- https://github.com/deivid-rodriguez/pry-byebug:embed



## Webアプリケーション内で任意のエラーを通知したい

エラーをフィルタリングしたい場合もありますが、任意のエラーを
Errbitで記録したい場合もあります。その場合は`Airbrake.notify()`を使用します。

下記のコードはrails consoleを使用したテストです。

```
$ bundle exec rails console

[1] pry(main)> require 'airbrake-ruby'
[2] pry(main)> Airbrake.notify('App crashed!')
```

設定した状態で、上記のコマンドを実行すると、通知がErrbitへ送信されます。
詳細はErrbitのWebUI上で確認できます。

より細かい実装をしたい場合は

- https://github.com/airbrake/airbrake-ruby

を確認してください。


## 最後に

導入し始めた当初は、不要なエラー通知が多くきましたが、フィルターを使うことによって通知を削減できました。
任意のエラー通知は、テストしただけで試せていませんが、エラー詳細を確認するのに便利そうです。