通过Kibana4对Rails应用进行可视化,使用EC2 Amazon Linux作为服务器

由于Rails和Kibana中的新信息尚未整理好,所以我做了总结。

能够出来的事情 de

    • Rails logの可視化

アプリの速度の分析、高速化などに使える

デプロイ時に、各種数値変化をリアルタイムでモニタリングできる(切り戻しの判断)

ステータスコードの割合
処理時間の分布

クローラーや、PC、スマフォなどのユーザーの動向を分析
特定のユーザーの行動を追うことが出来る(運用保守)

image
image

由于这只是试验,所以我们在许多方面作出了妥协。

Kibana 4.4.1 和 Elasticsearch 2.2
网络和安全组设置略过。
前提条件是:Kibana 和 Rails 服务器在同一网络中,通过私有IP进行通信。

准备在Rails下

gem "lograge"        #elastic_search用 log整形
gem "logstash-event" #elastic_serach用ログをカスタマイズ
gem "rack-user_agent" #requestから、os, browserのバージョンが分かる(ログに情報をだしたいために利用)

只需一个选项,用中文重新表达如下句子:
本来应该直接将日志发送到fluentd代理,但因为不知道如何操作,所以我决定先将日志输出并通过tail监控传给fluentd。这些日志是单独输出到另一个文件而不是常规日志中。

unless Rails.env.test? #テストの時以外を想定
  #fluentdがtailする用のログを設定
  path                                   = "#{Rails.root}/log/lograge_#{Rails.env}.log"
  #100Mごとに捨てる(ローテート設定)
  config.lograge.logger                  = ActiveSupport::Logger.new(path, 1, 100.megabytes)
  config.lograge.enabled                 = true
  config.lograge.keep_original_rails_log = true
  config.lograge.formatter               = Lograge::Formatters::Logstash.new

  config.lograge.custom_options = lambda do |event|
    opts = { host:            event.payload[:host],
             user_id:         event.payload[:user_id],
             remote_ip:       event.payload[:remote_ip],
             user_agent:      event.payload[:user_agent],
             os:              event.payload[:os],
             os_version:      event.payload[:os_version],
             browser:         event.payload[:browser],
             browser_version: event.payload[:browser_version],
             es:              event.payload[:elasticsearch_runtime],
             category:        event.payload[:category_name], #アプリの出したい情報など
             time:            event.time }

    #error時のバックトレースなんかも見れたら保守が便利なので出す
    if stacktrace = event.payload[:stacktrace] 
      opts[:stacktrace]    = stacktrace
      opts[:error]         = event.payload[:error]
      opts[:error_message] = event.payload[:error_message]
    end
    opts
  end
end

protect_from_forgery #←この記述はもともとあるはず、アプリの要件に合わせてオプションを記述、この記述がないとログが出力されない(csrf関連のrailsの設定)

def append_info_to_payload(payload)
  super
  payload[:host]                = request.host
  payload[:user_id]             = current_user.try(:id).to_s
  payload[:remote_ip]           = request.remote_ip
  payload[:user_agent]          = request.user_agent
  payload[:os]                  = request.os
  payload[:os_version]          = request.os_version
  payload[:browser]             = request.browser
  payload[:browser_version]     = request.browser_version
  payload[:category_name]       = params.try(:[], :category_name) #アプリの出したい情報
end

为了输出堆栈跟踪信息,我们使用了一个针对Rails 4.2.5的Monkey Patch。如果使用其他版本的Rails,请确保进行确认。
我们修正了位于actionpack-4.2.5/lib/action_controller/metal/instrumentation.rb中赋值response.status的异常处理部分,并添加了额外的信息。

此外,若在开发环境中升级Rails版本后,需让其崩溃(因为如果只有这里保持旧状态,应用程序的运行会出现问题)。

module ActionController
  module Instrumentation
    def process_action(*args)
      if Rails.env.development? && Rails.version != "4.2.5"
        raise "#20年後の僕へ、4.2.5の時のgemの内容をコピーして持ってきています.バージョンがあがったら確認して, 変更があればコピーして下さい。actionpack-4.2.5/lib/action_controller/metal/instrumentation.rb"
      end
      raw_payload = {
        controller: self.class.name,
        action: self.action_name,
        params: request.filtered_parameters,
        format: request.format.try(:ref),
        method: request.request_method,
        path: (request.fullpath rescue "unknown")
      }

      ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)

      ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
        begin
          result = super
          payload[:status] = response.status
          result
        rescue => e
          #kibanaでstack_traceを見るために拡張している、他はそのまま
          payload[:error]         = e.class.name
          payload[:error_message] = e.message
          payload[:stacktrace]    = e.backtrace.join("\n\t")
          raise
        ensure
          append_info_to_payload(payload)
        end
      end
    end
  end
end

如果运行Rails应用,应该会输出日志。
使用jq执行tail命令来确认。

tail -f log/lograge_development.log | jq "."

在AWS中准备好(Elasticsearch Kibana的EC2实例)。

在创建亚马逊 Linux实例时,请注意虚拟化存储(如Amazon弹性块存储)。虚拟化存储对于Elasticsearch的运行来说已经足够。而且,它们非常容易且快速地准备好使用,这使其相当吸引人。然而,与本地存储相比,虚拟化存储在本质上较慢。

因此,我建议扩展根存储。
暂时将根存储设为20GB,进行下一步。

$ sudo yum update -y

将时间设定为日本时间。

$ sudo vim /etc/sysconfig/clock
ZONE="Asia/Tokyo"
$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ sudo reboot

安装 Elasticsearch 2.2

sudo yum -y install java-1.8.0-openjdk-devel.x86_64
sudo rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
sudo vim /etc/yum.repos.d/elasticsearch.repo
[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=http://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enabled=1
sudo yum install elasticsearch -y
sudo vim /etc/elasticsearch/elasticsearch.yml

如果不进行此设置,就无法从外部网络进行连接。

cluster.name: kibana_cluster #適当に名前つけとく
network.host: xxxx.xxxx.xxx.xxx #elasticsearchサーバーのip
http.port: 9200

启动

sudo /etc/init.d/elasticsearch start

确认

curl localhost:9200

安装插件(根据个人喜好)

sudo /usr/share/elasticsearch/bin/plugin install analysis-kuromoji
sudo /usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head
sudo /usr/share/elasticsearch/bin/plugin install royrusso/elasticsearch-HQ
sudo /etc/init.d/elasticsearch restart

安装Kibana 4.4.1版本。

curl -L -O https://download.elastic.co/kibana/kibana/kibana-4.4.1-linux-x64.tar.gz
tar xzvf kibana-4.4.1-linux-x64.tar.gz
vim kibana-4.4.1-linux-x64/config/kibana.yml
image

确认动作

./kibana-4.4.1-linux-x64/bin/kibana
image

由于为了启动背景服务而使用Nginx有点麻烦,暂时先妥协一下。

sudo ./kibana-4.4.1-linux-x64/bin/kibana  > ./kibana.log &

在中文字符上,这是关于Kibana运行测试的表达:http://xxxx.xxxx.xxxx.xxxx:5601/

准备运行在EC2上的Rails的fluentd。

安装Fluentd

sudo vi /etc/yum.repos.d/treasuredata.repo
[treasuredata]
name=TreasureData
baseurl=http://packages.treasure-data.com/redhat/$basearch
gpgcheck=0
sudo yum install td-agent -y
sudo chkconfig td-agent on
sudo /usr/lib64/fluent/ruby/bin/fluent-gem install --no-ri --no-rdoc fluent-plugin-elasticsearch
sudo vim /etc/td-agent/td-agent.conf
<source>
  type     tail
  format   json
  tag      rails
  path     /path/to/log/lograge_production.log
  pos_file /path/to/log/lograge_production.log.pos
  time_key time
</source>

<match rails>
  type elasticsearch
  retry_limit 5
  host xxxx.xxxx.xxxx.xxxx #elasticsearch ip
  port 9200
  logstash_format true
  logstash_prefix lograge
  flush_interval  1s
</match>

由于在权限方面启动会导致崩溃,因此需要更改fluentd以以root权限运行。

sudo vim /etc/init.d/td-agent
- DAEMON_ARGS=${DAEMON_ARGS---user td-agent}
+ DAEMON_ARGS=${DAEMON_ARGS---user root}
TD_AGENT_ARGS="${TD_AGENT_ARGS-/usr/sbin/td-agent --user root --group td-agent --log /var/log/td-agent/td-agent.log}"

开机

sudo /etc/init.d/td-agent start
# 必ずstatusで起動状態を確認する
sudo /etc/init.d/td-agent status

如果状态确认失败,我会查看日志

less /var/log/td-agent/td-agent.log

如果你能做到这一点,那么只要Rails运行,日志就会存储到elasticsearch中,并且应该可以在kibana中查看。

image

给出的链接和备忘录是提供参考的。

如果使用logstash-logger,可能不需要使用tail命令来完成。
关于stacktrace的部分,请参考Gist。
在Qiita上,有关于在Lograge中进行Rails日志记录的信息。

广告
将在 10 秒后关闭
bannerAds