概要
ElectronとRubyを組み合わせたアプリケーション開発において、
すべてのログをログファイルに記録する必要があったが、
GUIに一部のログを表示するため、コンソール出力もさせる必要があった。
参考の記事をもとに、ログファイルとコンソール両方に出力する方法を実装。
その実装と合わせて selenium-webdriver
とchrome-headless
を使用する時に問題が発生。
オンライン上に明確な解決策の指定はなかったたが、解決策が見つかったため投稿します。
エラー内容
どう考えても visit
の引数にはURLの文字列しか渡していないのに、
以下のエラーが出てドツボにはまっていました。
TypeError
no implicit conversion of Object into String
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/open-uri.rb:37:in `open'
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/open-uri.rb:37:in `open'
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/logger.rb:703:in `open_logfile'
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/logger.rb:695:in `set_dev'
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/logger.rb:635:in `initialize'
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/logger.rb:353:in `new'
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/logger.rb:353:in `initialize'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/logger.rb:121:in `new'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/logger.rb:121:in `create_logger'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/logger.rb:46:in `initialize'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver.rb:96:in `new'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver.rb:96:in `logger'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/service.rb:91:in `build_process'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/chrome/service.rb:37:in `start_process'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/service.rb:71:in `block in start'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/socket_lock.rb:39:in `locked'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/service.rb:69:in `start'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/chrome/driver.rb:43:in `initialize'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/driver.rb:44:in `new'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver/common/driver.rb:44:in `for'
/Library/Ruby/Gems/2.3.0/gems/selenium-webdriver-3.14.0/lib/selenium/webdriver.rb:86:in `for'
/Library/Ruby/Gems/2.3.0/gems/capybara-3.12.0/lib/capybara/selenium/driver.rb:30:in `browser'
/Library/Ruby/Gems/2.3.0/gems/capybara-3.12.0/lib/capybara/selenium/driver.rb:49:in `visit'
/Library/Ruby/Gems/2.3.0/gems/capybara-3.12.0/lib/capybara/session.rb:265:in `visit'
/Library/Ruby/Gems/2.3.0/gems/capybara-3.12.0/lib/capybara/dsl.rb:51:in `block (2 levels) in <module:DSL>'
Object
クラスをそのまま使ってるところなどそうないので、ピンと来た。
案の定、ログ出力をいじるコードを読み込まなければ上記エラーは出なかった。
問題のコード
default_out = Object.new
default_out.instance_eval{@file=open(file_path, "a")}
class << default_out
def write(str)
@file.write(str)
@file.flush
STDOUT.write(str)
end
end
$stdout = default_out
Object.new
の部分に問題があることはわかったが、
他の何に差し替えればよいのか、調べても出てこず。
違う方式で、ファイルとコンソールの療法にログ出力する方法が見つけられず試行錯誤した結果が以下の方法です。
解決策
Object.new
を STDOUT.dup
に置き換えるだけ。
default_out = STDOUT.dup
default_out.instance_eval{@file=open(file_path, "a")}
class << default_out
def write(str)
@file.write(str)
@file.flush
STDOUT.write(str)
end
end
$stdout = default_out
これにて一件落着。
何時間も解決策を求めて疲れました。