この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
以前の記事で紹介したTreasureData関連のgem 'td'をRailsにて使用していたところ、sidekiqより起動時に以下の警告メッセージが出てきました。
Disabling Treasure Data event logger.
原因は/config/treasure_data.yml を用意していなかったことでした。と書くと簡単ですが、ネットで検索しても原因が分からなかったので、gemのソースをステップ実行して原因を特定しました。今回はgemのソースを解析して原因を特定する手順について、実例を挙げて書いてみたいと思います。
問題の解決までに行ったこと
上記の警告メッセージが表示されてから、原因の特定までに行ったことを書いていきます。
0.事前準備
今回の問題に限らないですが、ステップ実行にてソースを追うのが、原因となる箇所の特定には有効かと思います。私の場合はpry-byebugというgemを使ってステップ実行するので、これを予めGemfileに記述してbundle install しておきます。
gem 'pry-byebug'
IDEを使用している方や、他のデバッカ(ruby debugger等)を使用している場合は、そちらの手順に従ってください。
1.警告メッセージの発生箇所を特定する
警告メッセージを出力している箇所を特定するため、gemをGrepします。私の場合はアプリ内の「vendor/bundle」フォルダにgemをインストールしているので、このフォルダ内をgrepしました。
$ find . -name "*.*" | xargs grep "Disabling Treasure Data event logger."
(略)
./ruby/2.1.0/gems/td-logger-0.3.23/lib/td/logger/agent/rails.rb: warn 'Disabling Treasure Data event logger.'
(略)
「./ruby/2.1.0/gems/td-logger-0.3.23/lib/td/logger/agent/rails.rb」というファイル内で、該当する警告を出しているようです。
2.ブレークポイントを設定
上記で検索した箇所から警告メッセージが出力されているのかを確認するため、ブレークポイントを設定します。pry-byebugでは「binding.pry」というコードを埋め込むことでブレークポイントとなります。ブレークポイントを設定したうえで、アプリを実行してみます。すると、こんな感じでブレークポイントで止まりました。
/td-logger-0.3.23/lib/td/logger/agent/rails.rb
14: def self.init(rails)
=> 15: binding.pry
16: c = Config.init
17: if c.disabled
18: warn 'Disabling Treasure Data event logger.'
19: ::TreasureData::Logger.open_null
20: return false
21: end
警告メッセージの箇所にブレークポイントを設定してもいいのですが、少しはそこに至るソースの動きを見たいので、手前にブレークポイントを設定しています。ステップ実行にてソースを一行ずつ実行し、「warn 'Disabling Treasure Data event logger.'」のステップが通ることを確認しました。
3.ステップイン
上記のソースを見てみると、警告メッセージが出る条件は「c.disabled」がtrueである場合のようです。で、この「c」とは一行上の「c = Config.init」で生成されています。クラス名が「Config」であることから、定義に関するクラスのようです。この辺りで、私は「・・・そう言えば定義ファイルとか何も用意していなかったなー」なんて考え始めました。Config.initが何を行っているかを見るため、再びブレークポイントでソースを止め、ステップインしてみます。
/td-logger-0.3.23/lib/td/logger/agent/rails/config.rb
58: def self.init
=> 59: c = Config.new
60: config_path = CONFIG_PATH.start_with?('/') ? CONFIG_PATH : "#{::Rails.root}/#{CONFIG_PATH}"
61:
62: if File.exist?(config_path)
63: c.load_file(config_path)
64: elsif File.exist?(CONFIG_PATH_EY_DEPLOY)
65: c.load_file_ey(CONFIG_PATH_EY_DEPLOY)
66: elsif File.exist?(CONFIG_PATH_EY_LOCAL)
67: c.load_file_ey(CONFIG_PATH_EY_LOCAL)
68: else
69: c.load_env
70: end
71:
72: return c
「config_path」を取得し(60行目)、存在すれば「config_path」のファイルを読み込み(63行目)、存在しなければ順次別のファイルの存在を確認しているようです(64行目以降)。デバッカで「config_path」変数の値を確認したところ、以下のように表示されました。
$ p config_path
アプリパス/config/treasure_data.yml
この「/config/treasure_data.yml」を用意していなかったので、これを作成して再実行したところ、無事警告は出なくなりました。因みにこのファイルについても、以前の記事で書いていましたorz。
まとめ
ダラダラと書きましたが、こんな手順で今回は問題を解決しました。検索してもエラーの原因が特定できない場合、Rubyの場合はgemをステップ実行することで解決できることもあります。そのような場合の一助になれば幸いです。